diff --git a/.github/workflows/publish_npm_coinbase_x402.yml b/.github/workflows/publish_npm_coinbase_x402.yml index 319b7b84a..842bb2b58 100644 --- a/.github/workflows/publish_npm_coinbase_x402.yml +++ b/.github/workflows/publish_npm_coinbase_x402.yml @@ -32,7 +32,7 @@ jobs: pnpm -r --filter=x402 --filter=@coinbase/x402 run build - name: Publish coinbase-x402 package - working-directory: ./typescript/packages/coinbase-x402 + working-directory: ./typescript/packages/legacy/coinbase-x402 run: | # Get package information directly PACKAGE_NAME=$(node -p "require('./package.json').name") diff --git a/.github/workflows/publish_npm_x402.yml b/.github/workflows/publish_npm_x402.yml index 3bde5dab2..d007f8b52 100644 --- a/.github/workflows/publish_npm_x402.yml +++ b/.github/workflows/publish_npm_x402.yml @@ -32,7 +32,7 @@ jobs: pnpm -r --filter=x402 run build - name: Publish x402 package - working-directory: ./typescript/packages/x402 + working-directory: ./typescript/packages/legacy/x402 run: | # Get package information directly PACKAGE_NAME=$(node -p "require('./package.json').name") diff --git a/.github/workflows/publish_npm_x402_axios.yml b/.github/workflows/publish_npm_x402_axios.yml index 824a5289d..35bf3ad05 100644 --- a/.github/workflows/publish_npm_x402_axios.yml +++ b/.github/workflows/publish_npm_x402_axios.yml @@ -32,7 +32,7 @@ jobs: pnpm -r --filter=x402 --filter=x402-axios run build - name: Publish x402-axios package - working-directory: ./typescript/packages/x402-axios + working-directory: ./typescript/packages/legacy/x402-axios run: | # Get package information directly PACKAGE_NAME=$(node -p "require('./package.json').name") diff --git a/.github/workflows/publish_npm_x402_express.yml b/.github/workflows/publish_npm_x402_express.yml index 385fc63a3..e395e436d 100644 --- a/.github/workflows/publish_npm_x402_express.yml +++ b/.github/workflows/publish_npm_x402_express.yml @@ -32,7 +32,7 @@ jobs: pnpm -r --filter=x402 --filter=x402-express run build - name: Publish x402-express package - working-directory: ./typescript/packages/x402-express + working-directory: ./typescript/packages/legacy/x402-express run: | # Get package information directly PACKAGE_NAME=$(node -p "require('./package.json').name") diff --git a/.github/workflows/publish_npm_x402_fetch.yml b/.github/workflows/publish_npm_x402_fetch.yml index 471e9722c..c7470dfa3 100644 --- a/.github/workflows/publish_npm_x402_fetch.yml +++ b/.github/workflows/publish_npm_x402_fetch.yml @@ -32,7 +32,7 @@ jobs: pnpm -r --filter=x402 --filter=x402-fetch run build - name: Publish x402-fetch package - working-directory: ./typescript/packages/x402-fetch + working-directory: ./typescript/packages/legacy/x402-fetch run: | # Get package information directly PACKAGE_NAME=$(node -p "require('./package.json').name") diff --git a/.github/workflows/publish_npm_x402_hono.yml b/.github/workflows/publish_npm_x402_hono.yml index 6529c3bb9..aac955461 100644 --- a/.github/workflows/publish_npm_x402_hono.yml +++ b/.github/workflows/publish_npm_x402_hono.yml @@ -26,7 +26,7 @@ jobs: pnpm -r --filter=x402 --filter=x402-hono run build - name: Publish x402-hono package - working-directory: ./typescript/packages/x402-hono + working-directory: ./typescript/packages/legacy/x402-hono run: | # Get package information directly PACKAGE_NAME=$(node -p "require('./package.json').name") diff --git a/.github/workflows/publish_npm_x402_next.yml b/.github/workflows/publish_npm_x402_next.yml index ddde392ee..7ca52117a 100644 --- a/.github/workflows/publish_npm_x402_next.yml +++ b/.github/workflows/publish_npm_x402_next.yml @@ -26,7 +26,7 @@ jobs: pnpm -r --filter=x402 --filter=x402-next run build - name: Publish x402-next package - working-directory: ./typescript/packages/x402-next + working-directory: ./typescript/packages/legacy/x402-next run: | # Get package information directly PACKAGE_NAME=$(node -p "require('./package.json').name") diff --git a/e2e/.env-local b/e2e/.env-local new file mode 100644 index 000000000..30e4c95c4 --- /dev/null +++ b/e2e/.env-local @@ -0,0 +1,11 @@ +# E2E Test Configuration +SERVER_EVM_ADDRESS= +SERVER_SVM_ADDRESS= +CLIENT_EVM_PRIVATE_KEY= +CLIENT_SVM_PRIVATE_KEY= + +# Server Configuration +SERVER_PORT= +USE_CDP_FACILITATOR= +CDP_API_KEY_ID= +CDP_API_KEY_SECRET= diff --git a/e2e/README.md b/e2e/README.md index 7df3f2410..96f738b17 100644 --- a/e2e/README.md +++ b/e2e/README.md @@ -22,6 +22,10 @@ pnpm test -d -v # Test with verbose logging pnpm test -d -ts # Test TypeScript implementations pnpm test -d -py # Test Python implementations pnpm test -d -go # Test Go implementations + +# Legacy compatibility testing +pnpm test --legacy # Include legacy implementations +pnpm test --legacy -d -ts # Test legacy + new TypeScript implementations ``` ## Filtering Tests @@ -74,15 +78,34 @@ pnpm test -d -py --client=httpx # Python httpx client development pnpm test -ts -py # Test TypeScript/Python compatibility pnpm test -d -py -go # Test Python/Go on testnet +# Legacy Compatibility Testing +pnpm test --legacy -d # Test both new and legacy implementations +pnpm test --legacy --client=legacy-axios # Test specific legacy client with new servers +pnpm test --legacy --server=legacy-express # Test specific legacy server with new clients + # Production Testing pnpm test --prod=true -ts # Test TypeScript in production pnpm test --network=base -py # Test Python on base network ``` +### Environment Variables + +Required environment variables (set in `.env` file): +```bash +CLIENT_EVM_PRIVATE_KEY=0x... # Private key for client wallet +CLIENT_SVM_PRIVATE_KEY=... # Solana private key for client +SERVER_EVM_ADDRESS=0x... # Server's EVM payment address +SERVER_SVM_ADDRESS=... # Server's Solana payment address + +# Optional (for real blockchain facilitator) +EVM_RPC_URL=https://sepolia.base.org # RPC endpoint for blockchain access (defaults to Base Sepolia) +``` + ### Environment Options ```bash -d, --dev # Development mode (testnet, no CDP) -v, --verbose # Detailed logging +--legacy # Include legacy implementations from /legacy directory --log-file= # Save output to file ``` diff --git a/e2e/TODO.md b/e2e/TODO.md new file mode 100644 index 000000000..635206948 --- /dev/null +++ b/e2e/TODO.md @@ -0,0 +1,64 @@ +# End-to-End Testing TODO + +## Overview + +The e2e test suite validates the complete x402 payment flow across different client and server implementations, ensuring protocol compliance and interoperability between all SDKs. + +## Current Status + +### Implemented +- āœ… Express server (TypeScript) - reference implementation +- āœ… Fetch client (TypeScript) - reference implementation +- āœ… Test harness with automatic discovery and execution +- āœ… Support for both v1 and v2 protocol testing + +### Pending Implementation +- šŸ”„ Hono server (TypeScript) +- šŸ”„ Next.js server (TypeScript) +- šŸ”„ Axios client (TypeScript) +- šŸ”„ Python servers (FastAPI, Flask) +- šŸ”„ Python clients (httpx, requests) +- šŸ”„ Go servers (Gin) +- šŸ”„ Go clients + +## Facilitator Support + +### Local Facilitators +Add one facilitator implementation per language in `/facilitators/`: +- `/facilitators/typescript` - TypeScript facilitator implementation +- `/facilitators/python` - Python facilitator implementation +- `/facilitators/go` - Go facilitator implementation + +### Remote Facilitators +Add configuration support for external facilitator services: +- x402.org facilitator +- CDP (Coinbase Developer Platform) facilitator +- Custom facilitator endpoints + +## Test Runner Improvements + +### Configuration Flags +Enhance the test runner to support: +- `--facilitator` flag to select which facilitator(s) to use + - `local` - Use local facilitator implementations + - `x402` - Use x402.org facilitator + - `cdp` - Use CDP facilitator + - `all` - Test against all available facilitators +- `--client` flag to filter which clients to test +- `--server` flag to filter which servers to test +- `--protocol-version` flag to test specific protocol versions (v1, v2, or both) + +### Test Matrix +Implement comprehensive testing matrix: +- All client Ɨ server combinations +- All facilitator options +- Both protocol versions where applicable +- Different payment mechanisms (EVM, Solana, etc.) + +## Protocol Files + +The test suite uses standardized protocols for communication: +- `/e2e/servers/text-server-protocol.txt` - Server implementation requirements +- `/e2e/clients/text-client-protocol.txt` - Client implementation requirements + +All new implementations must follow these protocols to ensure compatibility with the test harness. \ No newline at end of file diff --git a/e2e/clients/fetch/index.ts b/e2e/clients/fetch/index.ts index e7625705a..aaac1ffc0 100644 --- a/e2e/clients/fetch/index.ts +++ b/e2e/clients/fetch/index.ts @@ -1,51 +1,64 @@ import { config } from "dotenv"; -import { Hex } from "viem"; -import { createSigner, decodeXPaymentResponse, MultiNetworkSigner, wrapFetchWithPayment } from "x402-fetch"; +import { wrapFetchWithPayment, decodePaymentResponseHeader } from "@x402/fetch"; +import { privateKeyToAccount } from "viem/accounts"; +import { ExactEvmClient } from "@x402/evm"; +import { ExactEvmClientV1 } from "@x402/evm/v1"; config(); -const evmPrivateKey = process.env.EVM_PRIVATE_KEY as Hex; -const svmPrivateKey = process.env.SVM_PRIVATE_KEY as string; const baseURL = process.env.RESOURCE_SERVER_URL as string; const endpointPath = process.env.ENDPOINT_PATH as string; const url = `${baseURL}${endpointPath}`; +const account = privateKeyToAccount(process.env.EVM_PRIVATE_KEY as `0x${string}`); -if (!baseURL || !evmPrivateKey || !svmPrivateKey || !endpointPath) { - console.error("Missing required environment variables"); - process.exit(1); -} - -const evmSigner = await createSigner("base-sepolia", evmPrivateKey); -const svmSigner = await createSigner("solana-devnet", svmPrivateKey); -const account = { evm: evmSigner, svm: svmSigner } as MultiNetworkSigner; - -const fetchWithPayment = wrapFetchWithPayment(fetch, account); +const fetchWithPayment = wrapFetchWithPayment(fetch, { + schemes: [ + { + network: "eip155:*", + client: new ExactEvmClient(account), + }, + { + network: "base-sepolia" as `${string}:${string}`, + x402Version: 1, + client: new ExactEvmClientV1(account), + }, + { + network: "base" as `${string}:${string}`, + x402Version: 1, + client: new ExactEvmClientV1(account), + }, + ], +}); fetchWithPayment(url, { method: "GET", -}) - .then(async response => { - const data = await response.json(); - const paymentResponse = response.headers.get("x-payment-response"); +}).then(async response => { + const data = await response.json(); + // Check both v2 (PAYMENT-RESPONSE) and v1 (X-PAYMENT-RESPONSE) headers + const paymentResponse = response.headers.get("PAYMENT-RESPONSE") || response.headers.get("X-PAYMENT-RESPONSE"); + if (!paymentResponse) { + // No payment was required const result = { success: true, data: data, status_code: response.status, - payment_response: decodeXPaymentResponse(paymentResponse!) }; - - // Output structured result as JSON for proxy to parse console.log(JSON.stringify(result)); process.exit(0); - }) - .catch(error => { - const errorResult = { - success: false, - error: error.message || String(error), - status_code: error.response?.status - }; + return; + } + + const decodedPaymentResponse = decodePaymentResponseHeader(paymentResponse); + + const result = { + success: decodedPaymentResponse.success, + data: data, + status_code: response.status, + payment_response: decodedPaymentResponse, + }; - console.log(JSON.stringify(errorResult)); - process.exit(1); - }); + // Output structured result as JSON for proxy to parse + console.log(JSON.stringify(result)); + process.exit(0); +}); diff --git a/e2e/clients/fetch/package.json b/e2e/clients/fetch/package.json index f079ea58f..292f2bf04 100644 --- a/e2e/clients/fetch/package.json +++ b/e2e/clients/fetch/package.json @@ -1,5 +1,5 @@ { - "name": "fetch-client-example", + "name": "@x402/fetch-e2e", "private": true, "type": "module", "scripts": { @@ -13,7 +13,9 @@ "axios": "^1.7.9", "dotenv": "^16.4.7", "viem": "^2.21.26", - "x402-fetch": "workspace:*" + "@x402/evm": "workspace:*", + "@x402/core": "workspace:*", + "@x402/fetch": "workspace:*" }, "devDependencies": { "@eslint/js": "^9.24.0", diff --git a/e2e/clients/fetch/test.config.json b/e2e/clients/fetch/test.config.json index f738ce6da..3e00b24c3 100644 --- a/e2e/clients/fetch/test.config.json +++ b/e2e/clients/fetch/test.config.json @@ -3,13 +3,15 @@ "type": "client", "language": "typescript", "protocolFamilies": [ - "evm", - "svm" + "evm" + ], + "x402Versions": [ + 1, + 2 ], "environment": { "required": [ "EVM_PRIVATE_KEY", - "SVM_PRIVATE_KEY", "RESOURCE_SERVER_URL", "ENDPOINT_PATH" ], diff --git a/e2e/clients/fetch/tsconfig.json b/e2e/clients/fetch/tsconfig.json index 81e0e7f1f..1bdf94ca8 100644 --- a/e2e/clients/fetch/tsconfig.json +++ b/e2e/clients/fetch/tsconfig.json @@ -9,11 +9,7 @@ "strict": true, "resolveJsonModule": true, "baseUrl": ".", - "types": [ - "node" - ] + "types": ["node"] }, - "include": [ - "index.ts" - ] -} \ No newline at end of file + "include": ["index.ts"] +} diff --git a/e2e/clients/go-http/README.md b/e2e/clients/go-http/README.md new file mode 100644 index 000000000..96e40854e --- /dev/null +++ b/e2e/clients/go-http/README.md @@ -0,0 +1,100 @@ +# x402 Go HTTP Client + +This is an example Go client that demonstrates how to use the x402 Go SDK's HTTP client to make requests to endpoints protected by the x402 payment protocol. + +## Prerequisites + +- Go 1.21+ +- A running x402 server (you can use the example express server) +- A valid Ethereum private key for making payments + +## Features + +- Supports both x402 v1 and v2 protocols +- Automatic payment handling for 402 responses +- EVM support with EIP-3009 TransferWithAuthorization +- Compatible with both v1 (legacy) and v2 payment requirements + +## Setup + +1. Install dependencies: +```bash +go mod tidy +``` + +2. Set environment variables: +```bash +export EVM_PRIVATE_KEY="your_private_key_here" +export RESOURCE_SERVER_URL="http://localhost:4021" +export ENDPOINT_PATH="/protected" +``` + +3. Run the client: +```bash +go run main.go +``` + +## How It Works + +The client: +1. Creates an x402 HTTP client with EVM support +2. Registers both v1 and v2 EVM implementations for backward compatibility +3. Wraps the standard Go HTTP client with payment handling +4. Makes a request to the protected endpoint +5. Automatically handles 402 Payment Required responses +6. Creates and submits the appropriate payment +7. Retries the request with the payment signature +8. Outputs the result as JSON for the e2e test framework + +## Example Output + +Success: +```json +{ + "success": true, + "data": { + "message": "Protected endpoint accessed successfully", + "timestamp": "2024-01-01T00:00:00Z" + }, + "status_code": 200, + "payment_response": { + "success": true, + "transaction": "0x...", + "network": "eip155:84532", + "payer": "0x..." + } +} +``` + +Error: +```json +{ + "success": false, + "error": "Request failed: payment retry limit exceeded" +} +``` + +## Implementation Details + +### EVM Signer + +The client uses a real EVM signer that: +- Derives the address from the private key +- Implements proper EIP-712 (typed data) signing +- Uses go-ethereum's apitypes for structured data signing +- Generates valid Ethereum signatures with recovery ID + +### Payment Handling + +The HTTP client wrapper: +- Intercepts 402 responses +- Extracts payment requirements from headers (v2) or body (v1) +- Creates appropriate payment payloads +- Retries requests with payment signatures +- Prevents infinite retry loops + +### Version Support + +The client registers handlers for both: +- **v2 (default)**: Modern x402 protocol with header-based communication +- **v1 (legacy)**: Backward compatibility with body-based requirements diff --git a/e2e/clients/go-http/go.mod b/e2e/clients/go-http/go.mod new file mode 100644 index 000000000..f272f84a9 --- /dev/null +++ b/e2e/clients/go-http/go.mod @@ -0,0 +1,33 @@ +module github.com/coinbase/x402-go/e2e/clients/go-http + +go 1.23.0 + +toolchain go1.24.1 + +require ( + github.com/coinbase/x402-go/v2 v2.0.0 + github.com/ethereum/go-ethereum v1.14.11 +) + +require ( + github.com/bits-and-blooms/bitset v1.13.0 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect + github.com/consensys/bavard v0.1.13 // indirect + github.com/consensys/gnark-crypto v0.12.1 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c // indirect + github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/ethereum/c-kzg-4844 v1.0.0 // indirect + github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 // indirect + github.com/holiman/uint256 v1.3.1 // indirect + github.com/mmcloughlin/addchain v0.4.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/supranational/blst v0.3.13 // indirect + golang.org/x/crypto v0.40.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.35.0 // indirect + rsc.io/tmplfunc v0.0.3 // indirect +) + +replace github.com/coinbase/x402-go/v2 => ../../../go diff --git a/e2e/clients/go-http/go.sum b/e2e/clients/go-http/go.sum new file mode 100644 index 000000000..4baaa84fc --- /dev/null +++ b/e2e/clients/go-http/go.sum @@ -0,0 +1,128 @@ +github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= +github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= +github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= +github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= +github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= +github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v1.1.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA= +github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= +github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= +github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= +github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= +github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c h1:uQYC5Z1mdLRPrZhHjHxufI8+2UG/i25QG92j0Er9p6I= +github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= +github.com/crate-crypto/go-kzg-4844 v1.0.0 h1:TsSgHwrkTKecKJ4kadtHi4b3xHW5dCFUDFnUp1TsawI= +github.com/crate-crypto/go-kzg-4844 v1.0.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA= +github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/ethereum/go-ethereum v1.14.11 h1:8nFDCUUE67rPc6AKxFj7JKaOa2W/W1Rse3oS6LvvxEY= +github.com/ethereum/go-ethereum v1.14.11/go.mod h1:+l/fr42Mma+xBnhefL/+z11/hcmJ2egl+ScIVPjhc7E= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 h1:8NfxH2iXvJ60YRB8ChToFTUzl8awsc3cJ8CbLjGIl/A= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs= +github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= +github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= +github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.12.0 h1:C+UIj/QWtmqY13Arb8kwMt5j34/0Z2iKamrJ+ryC0Gg= +github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a h1:CmF68hwI0XsOQ5UwlBopMi2Ow4Pbg32akc4KIVCOm+Y= +github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk= +github.com/supranational/blst v0.3.13/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= +google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= +google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/e2e/clients/go-http/main b/e2e/clients/go-http/main new file mode 100755 index 000000000..eb5cd65e6 Binary files /dev/null and b/e2e/clients/go-http/main differ diff --git a/e2e/clients/go-http/main.go b/e2e/clients/go-http/main.go new file mode 100644 index 000000000..a1dbfbfdb --- /dev/null +++ b/e2e/clients/go-http/main.go @@ -0,0 +1,279 @@ +package main + +import ( + "context" + "crypto/ecdsa" + "encoding/json" + "fmt" + "log" + "math/big" + "net/http" + "os" + "strings" + + x402 "github.com/coinbase/x402-go/v2" + x402http "github.com/coinbase/x402-go/v2/http" + "github.com/coinbase/x402-go/v2/mechanisms/evm" + evmv1 "github.com/coinbase/x402-go/v2/mechanisms/evm/v1" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/signer/core/apitypes" +) + +// Result structure for e2e test output +type Result struct { + Success bool `json:"success"` + Data interface{} `json:"data,omitempty"` + StatusCode int `json:"status_code,omitempty"` + PaymentResponse interface{} `json:"payment_response,omitempty"` + Error string `json:"error,omitempty"` +} + +// Real EVM signer for client using EIP-712 +type clientEvmSigner struct { + privateKey *ecdsa.PrivateKey + address common.Address +} + +func newClientEvmSigner(privateKeyHex string) (*clientEvmSigner, error) { + // Remove 0x prefix if present + privateKeyHex = strings.TrimPrefix(privateKeyHex, "0x") + + privateKey, err := crypto.HexToECDSA(privateKeyHex) + if err != nil { + return nil, fmt.Errorf("failed to parse private key: %w", err) + } + + address := crypto.PubkeyToAddress(privateKey.PublicKey) + + return &clientEvmSigner{ + privateKey: privateKey, + address: address, + }, nil +} + +func (s *clientEvmSigner) Address() string { + return s.address.Hex() +} + +func (s *clientEvmSigner) SignTypedData( + domain evm.TypedDataDomain, + types map[string][]evm.TypedDataField, + primaryType string, + message map[string]interface{}, +) ([]byte, error) { + // Convert our types to go-ethereum's EIP-712 types + typedData := apitypes.TypedData{ + Types: make(apitypes.Types), + PrimaryType: primaryType, + Domain: apitypes.TypedDataDomain{ + Name: getStringFromInterface(domain.Name), + Version: getStringFromInterface(domain.Version), + ChainId: getBigIntFromInterface(domain.ChainID), + VerifyingContract: getStringFromInterface(domain.VerifyingContract), + }, + Message: message, + } + + // Convert types + for typeName, fields := range types { + typedFields := make([]apitypes.Type, len(fields)) + for i, field := range fields { + typedFields[i] = apitypes.Type{ + Name: field.Name, + Type: field.Type, + } + } + typedData.Types[typeName] = typedFields + } + + // Add EIP712Domain type if not present + if _, exists := typedData.Types["EIP712Domain"]; !exists { + typedData.Types["EIP712Domain"] = []apitypes.Type{ + {Name: "name", Type: "string"}, + {Name: "version", Type: "string"}, + {Name: "chainId", Type: "uint256"}, + {Name: "verifyingContract", Type: "address"}, + } + } + + // Sign the typed data + dataHash, err := typedData.HashStruct(typedData.PrimaryType, typedData.Message) + if err != nil { + return nil, fmt.Errorf("failed to hash struct: %w", err) + } + + domainSeparator, err := typedData.HashStruct("EIP712Domain", typedData.Domain.Map()) + if err != nil { + return nil, fmt.Errorf("failed to hash domain: %w", err) + } + + // Create the digest to sign + rawData := []byte{0x19, 0x01} + rawData = append(rawData, domainSeparator...) + rawData = append(rawData, dataHash...) + digest := crypto.Keccak256(rawData) + + // Sign the digest + signature, err := crypto.Sign(digest, s.privateKey) + if err != nil { + return nil, fmt.Errorf("failed to sign: %w", err) + } + + // Adjust v value for Ethereum (27 or 28) + signature[64] += 27 + + return signature, nil +} + +// Helper functions to convert interface{} to specific types +func getStringFromInterface(v interface{}) string { + if v == nil { + return "" + } + if s, ok := v.(string); ok { + return s + } + return fmt.Sprintf("%v", v) +} + +func getBigIntFromInterface(v interface{}) *math.HexOrDecimal256 { + if v == nil { + return nil + } + switch val := v.(type) { + case *big.Int: + return (*math.HexOrDecimal256)(val) + case string: + n, _ := new(big.Int).SetString(val, 10) + return (*math.HexOrDecimal256)(n) + case int64: + return (*math.HexOrDecimal256)(big.NewInt(val)) + case float64: + return (*math.HexOrDecimal256)(big.NewInt(int64(val))) + default: + return nil + } +} + +func main() { + // Get configuration from environment + serverURL := os.Getenv("RESOURCE_SERVER_URL") + if serverURL == "" { + log.Fatal("RESOURCE_SERVER_URL is required") + } + + endpointPath := os.Getenv("ENDPOINT_PATH") + if endpointPath == "" { + endpointPath = "/protected" + } + + evmPrivateKey := os.Getenv("EVM_PRIVATE_KEY") + if evmPrivateKey == "" { + log.Fatal("EVM_PRIVATE_KEY is required") + } + + // Create the signer + signer, err := newClientEvmSigner(evmPrivateKey) + if err != nil { + outputError(fmt.Sprintf("Failed to create signer: %v", err)) + return + } + + // Create x402 HTTP client + httpClient := x402http.Newx402HTTPClient() + + // Register EVM v2 client for all EIP155 networks + evmClient := evm.NewExactEvmClient(signer) + httpClient.RegisterScheme("eip155:*", evmClient) + + // Register EVM v1 client for base-sepolia (v1 network name) + evmClientV1 := evmv1.NewExactEvmClientV1(signer) + httpClient.RegisterSchemeV1("base-sepolia", evmClientV1) + + // Wrap standard HTTP client with payment handling + client := x402http.WrapHTTPClientWithPayment(http.DefaultClient, httpClient) + + // Make the request + url := serverURL + endpointPath + ctx := context.Background() + + req, err := http.NewRequestWithContext(ctx, "GET", url, nil) + if err != nil { + outputError(fmt.Sprintf("Failed to create request: %v", err)) + return + } + + // Perform the request (payment will be handled automatically if needed) + resp, err := client.Do(req) + if err != nil { + outputError(fmt.Sprintf("Request failed: %v", err)) + return + } + defer resp.Body.Close() + + // Read response body + var responseData interface{} + if err := json.NewDecoder(resp.Body).Decode(&responseData); err != nil { + outputError(fmt.Sprintf("Failed to decode response: %v", err)) + return + } + + // Extract payment response from headers if present + var paymentResponse interface{} + if paymentHeader := resp.Header.Get("PAYMENT-RESPONSE"); paymentHeader != "" { + settleResp, err := httpClient.GetPaymentSettleResponse(map[string]string{ + "PAYMENT-RESPONSE": paymentHeader, + }) + if err == nil { + paymentResponse = settleResp + } + } else if paymentHeader := resp.Header.Get("X-PAYMENT-RESPONSE"); paymentHeader != "" { + settleResp, err := httpClient.GetPaymentSettleResponse(map[string]string{ + "X-PAYMENT-RESPONSE": paymentHeader, + }) + if err == nil { + paymentResponse = settleResp + } + } + + // Check if payment was successful (if a payment was required) + success := true + if resp.StatusCode == 402 { + // Payment was required but we got a 402, so payment failed + success = false + } else if settleResp, ok := paymentResponse.(*x402.SettleResponse); ok && paymentResponse != nil { + // Payment was attempted, check if it succeeded + success = settleResp.Success + } + + // Output result + result := Result{ + Success: success, + Data: responseData, + StatusCode: resp.StatusCode, + PaymentResponse: paymentResponse, + } + + outputResult(result) +} + +func outputResult(result Result) { + data, err := json.Marshal(result) + if err != nil { + log.Fatalf("Failed to marshal result: %v", err) + } + fmt.Println(string(data)) + os.Exit(0) +} + +func outputError(errorMsg string) { + result := Result{ + Success: false, + Error: errorMsg, + } + data, _ := json.Marshal(result) + fmt.Println(string(data)) + os.Exit(1) +} diff --git a/e2e/clients/go-http/run.sh b/e2e/clients/go-http/run.sh new file mode 100755 index 000000000..5f2f5f850 --- /dev/null +++ b/e2e/clients/go-http/run.sh @@ -0,0 +1,2 @@ +#!/bin/bash +go run main.go diff --git a/e2e/clients/go-http/test.config.json b/e2e/clients/go-http/test.config.json new file mode 100644 index 000000000..981f74796 --- /dev/null +++ b/e2e/clients/go-http/test.config.json @@ -0,0 +1,20 @@ +{ + "name": "go-http", + "type": "client", + "language": "go", + "protocolFamilies": [ + "evm" + ], + "x402Versions": [ + 1, + 2 + ], + "environment": { + "required": [ + "EVM_PRIVATE_KEY", + "RESOURCE_SERVER_URL", + "ENDPOINT_PATH" + ], + "optional": [] + } +} \ No newline at end of file diff --git a/e2e/clients/text-client-protocol.txt b/e2e/clients/text-client-protocol.txt index f1ae00841..ad2e5ce22 100644 --- a/e2e/clients/text-client-protocol.txt +++ b/e2e/clients/text-client-protocol.txt @@ -11,6 +11,10 @@ Clients must declare which protocol families they support in their test.config.j - **EVM**: Ethereum Virtual Machine compatible networks (Base, Ethereum, etc.) - **SVM**: Solana Virtual Machine compatible networks (Solana, etc.) +## X402 Version Support +Clients must declare which x402 protocol versions they support using the `x402Versions` field: +- **x402Versions**: Array of supported x402 protocol versions (e.g., [1, 2]) + Example configuration: ```json { @@ -18,6 +22,7 @@ Example configuration: "type": "client", "language": "typescript", "protocolFamilies": ["evm"], + "x402Versions": [1, 2], "environment": { "required": ["EVM_PRIVATE_KEY", "RESOURCE_SERVER_URL", "ENDPOINT_PATH"], "optional": [] @@ -32,6 +37,7 @@ Multi-protocol client example: "type": "client", "language": "typescript", "protocolFamilies": ["evm", "svm"], + "x402Versions": [1, 2], "environment": { "required": ["EVM_PRIVATE_KEY", "SVM_PRIVATE_KEY", "RESOURCE_SERVER_URL", "ENDPOINT_PATH"], "optional": [] diff --git a/e2e/extensions/bazaar.ts b/e2e/extensions/bazaar.ts new file mode 100644 index 000000000..a8ebaa732 --- /dev/null +++ b/e2e/extensions/bazaar.ts @@ -0,0 +1,387 @@ +/** + * Bazaar Discovery Extension Validation for E2E Tests + * + * This module validates that the bazaar discovery extension is working correctly + * by checking that facilitators have discovered all expected endpoints from servers. + */ + +import { log, verboseLog, errorLog } from '../src/logger'; +import type { FacilitatorProxy, DiscoveredServer, TestConfig } from '../src/types'; + +/** + * Discovery resources response structure + */ +interface DiscoveryResourcesResponse { + x402Version: number; + items: Array<{ + resource: string; + type: string; + x402Version: number; + accepts: any[]; + discoveryInfo?: any; + lastUpdated: string; + metadata?: Record; + }>; + pagination: { + limit: number; + offset: number; + total: number; + }; +} + +/** + * Expected endpoint that should be discovered + */ +interface ExpectedDiscoverableEndpoint { + serverName: string; + serverUrl: string; + endpointPath: string; + method: string; + description: string; +} + +/** + * Validation result for a single facilitator + */ +interface FacilitatorDiscoveryResult { + facilitatorName: string; + facilitatorUrl: string; + totalDiscovered: number; + expectedEndpoints: ExpectedDiscoverableEndpoint[]; + discoveredEndpoints: string[]; + missingEndpoints: ExpectedDiscoverableEndpoint[]; + unexpectedEndpoints: string[]; + success: boolean; + error?: string; +} + +/** + * Overall discovery validation result + */ +export interface DiscoveryValidationResult { + totalFacilitators: number; + facilitatorsChecked: number; + facilitatorResults: FacilitatorDiscoveryResult[]; + totalExpectedEndpoints: number; + totalDiscoveredEndpoints: number; + allEndpointsDiscovered: boolean; + success: boolean; +} + +/** + * Check if a server supports the bazaar extension + */ +function serverSupportsBazaar(serverConfig: TestConfig): boolean { + return serverConfig.extensions?.includes('bazaar') ?? false; +} + +/** + * Check if a facilitator supports the bazaar extension + */ +function facilitatorSupportsBazaar(facilitatorConfig: TestConfig): boolean { + return facilitatorConfig.extensions?.includes('bazaar') ?? false; +} + +/** + * Get discoverable endpoints from a server config + */ +function getDiscoverableEndpoints( + server: DiscoveredServer, + serverPort: number +): ExpectedDiscoverableEndpoint[] { + if (!serverSupportsBazaar(server.config)) { + return []; + } + + const serverUrl = `http://localhost:${serverPort}`; + const discoverableEndpoints: ExpectedDiscoverableEndpoint[] = []; + + // Find all payment-required endpoints (these should have discovery info) + const paymentEndpoints = server.config.endpoints?.filter( + endpoint => endpoint.requiresPayment === true + ) || []; + + for (const endpoint of paymentEndpoints) { + discoverableEndpoints.push({ + serverName: server.config.name, + serverUrl, + endpointPath: endpoint.path, + method: endpoint.method, + description: endpoint.description, + }); + } + + return discoverableEndpoints; +} + +/** + * Fetch discovered resources from a facilitator + */ +async function fetchDiscoveredResources( + facilitatorProxy: FacilitatorProxy +): Promise { + try { + const url = `${facilitatorProxy.getUrl()}/discovery/resources?limit=1000`; + verboseLog(` šŸ“” Fetching discovered resources from: ${url}`); + + const response = await fetch(url); + + if (!response.ok) { + errorLog(` āŒ Failed to fetch discovery resources: ${response.status} ${response.statusText}`); + return null; + } + + const data = await response.json(); + return data as DiscoveryResourcesResponse; + } catch (error) { + errorLog(` āŒ Error fetching discovery resources: ${error instanceof Error ? error.message : String(error)}`); + return null; + } +} + +/** + * Validate discovery for a single facilitator + */ +async function validateFacilitatorDiscovery( + facilitatorProxy: FacilitatorProxy, + facilitatorConfig: TestConfig, + expectedEndpoints: ExpectedDiscoverableEndpoint[] +): Promise { + const facilitatorName = facilitatorConfig.name; + const facilitatorUrl = facilitatorProxy.getUrl(); + + verboseLog(`\n šŸ” Validating discovery for facilitator: ${facilitatorName}`); + verboseLog(` šŸ“ URL: ${facilitatorUrl}`); + + // Check if facilitator supports bazaar + if (!facilitatorSupportsBazaar(facilitatorConfig)) { + verboseLog(` ā­ļø Facilitator does not support bazaar extension, skipping`); + return { + facilitatorName, + facilitatorUrl, + totalDiscovered: 0, + expectedEndpoints: [], + discoveredEndpoints: [], + missingEndpoints: [], + unexpectedEndpoints: [], + success: true, // Not a failure if facilitator doesn't support bazaar + }; + } + + // Fetch discovered resources + const discoveryResponse = await fetchDiscoveredResources(facilitatorProxy); + + if (!discoveryResponse) { + return { + facilitatorName, + facilitatorUrl, + totalDiscovered: 0, + expectedEndpoints, + discoveredEndpoints: [], + missingEndpoints: expectedEndpoints, + unexpectedEndpoints: [], + success: false, + error: 'Failed to fetch discovery resources', + }; + } + + verboseLog(` šŸ“Š Total resources discovered: ${discoveryResponse.items.length}`); + + // Build set of discovered resource URLs for easy comparison + const discoveredUrls = new Set( + discoveryResponse.items.map(item => item.resource) + ); + + // Check which expected endpoints were discovered + const missingEndpoints: ExpectedDiscoverableEndpoint[] = []; + const discoveredEndpoints: string[] = []; + + for (const expected of expectedEndpoints) { + const expectedResourceUrl = `${expected.serverUrl}${expected.endpointPath}`; + + if (discoveredUrls.has(expectedResourceUrl)) { + discoveredEndpoints.push(expectedResourceUrl); + verboseLog(` āœ… Discovered: ${expected.method} ${expectedResourceUrl}`); + } else { + missingEndpoints.push(expected); + verboseLog(` āŒ Missing: ${expected.method} ${expectedResourceUrl}`); + } + } + + // Find any unexpected resources (discovered but not expected) + const expectedUrls = new Set( + expectedEndpoints.map(e => `${e.serverUrl}${e.endpointPath}`) + ); + const unexpectedEndpoints = discoveryResponse.items + .filter(item => !expectedUrls.has(item.resource)) + .map(item => item.resource); + + if (unexpectedEndpoints.length > 0) { + verboseLog(` ā„¹ļø Unexpected endpoints discovered: ${unexpectedEndpoints.length}`); + unexpectedEndpoints.forEach(url => verboseLog(` • ${url}`)); + } + + const success = missingEndpoints.length === 0; + + return { + facilitatorName, + facilitatorUrl, + totalDiscovered: discoveryResponse.items.length, + expectedEndpoints, + discoveredEndpoints, + missingEndpoints, + unexpectedEndpoints, + success, + }; +} + +/** + * Main discovery validation handler + * + * Validates that all expected endpoints have been discovered by facilitators + * + * @param facilitators - Array of facilitator proxies with their configs + * @param servers - Array of discovered servers with their configs + * @param serverPorts - Map of server name to port number + * @returns Validation result + * + * @example + * ```typescript + * const result = await handleDiscoveryValidation( + * facilitators.map(f => ({ proxy: f.proxy, config: f.config })), + * servers, + * new Map([['express', 4021], ['hono', 4022]]) + * ); + * + * if (!result.success) { + * console.error('Discovery validation failed'); + * } + * ``` + */ +export async function handleDiscoveryValidation( + facilitators: Array<{ proxy: FacilitatorProxy; config: TestConfig }>, + servers: DiscoveredServer[], + serverPorts: Map +): Promise { + log('\n╔════════════════════════════════════════════════════════╗'); + log('ā•‘ Bazaar Discovery Extension Validation ā•‘'); + log('ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•'); + + // Calculate all expected discoverable endpoints + const allExpectedEndpoints: ExpectedDiscoverableEndpoint[] = []; + + for (const server of servers) { + const serverPort = serverPorts.get(server.config.name); + if (!serverPort) { + verboseLog(` āš ļø No port found for server: ${server.config.name}, skipping`); + continue; + } + + const serverEndpoints = getDiscoverableEndpoints(server, serverPort); + allExpectedEndpoints.push(...serverEndpoints); + } + + log(`\nšŸ“‹ Expected Discoverable Endpoints: ${allExpectedEndpoints.length}`); + if (allExpectedEndpoints.length > 0) { + verboseLog(''); + allExpectedEndpoints.forEach(endpoint => { + verboseLog(` • ${endpoint.method} ${endpoint.serverUrl}${endpoint.endpointPath} (${endpoint.serverName})`); + }); + } + + // Validate each facilitator + const facilitatorResults: FacilitatorDiscoveryResult[] = []; + let facilitatorsChecked = 0; + let totalDiscovered = 0; + + for (const { proxy, config } of facilitators) { + const result = await validateFacilitatorDiscovery( + proxy, + config, + allExpectedEndpoints + ); + + facilitatorResults.push(result); + + if (facilitatorSupportsBazaar(config)) { + facilitatorsChecked++; + totalDiscovered += result.totalDiscovered; + } + } + + // Determine overall success + const allEndpointsDiscovered = facilitatorResults.every(r => r.success); + const hasExpectedEndpoints = allExpectedEndpoints.length > 0; + const success = !hasExpectedEndpoints || allEndpointsDiscovered; + + // Print summary + log('\n═══════════════════════════════════════════════════════'); + log(' Discovery Summary'); + log('═══════════════════════════════════════════════════════'); + log(`Total Facilitators: ${facilitators.length}`); + log(`Facilitators with Bazaar: ${facilitatorsChecked}`); + log(`Expected Endpoints: ${allExpectedEndpoints.length}`); + log(`Total Discovered Resources: ${totalDiscovered}`); + + // Print per-facilitator results + for (const result of facilitatorResults) { + if (!facilitatorSupportsBazaar(facilitators.find(f => f.config.name === result.facilitatorName)!.config)) { + continue; + } + + log(`\nšŸ“ ${result.facilitatorName}:`); + log(` Discovered: ${result.discoveredEndpoints.length}/${result.expectedEndpoints.length}`); + + if (result.missingEndpoints.length > 0) { + errorLog(` āŒ Missing: ${result.missingEndpoints.length}`); + result.missingEndpoints.forEach(endpoint => { + errorLog(` • ${endpoint.method} ${endpoint.serverUrl}${endpoint.endpointPath}`); + }); + } else if (result.expectedEndpoints.length > 0) { + log(` āœ… All expected endpoints discovered`); + } + + if (result.unexpectedEndpoints.length > 0) { + verboseLog(` ā„¹ļø Unexpected: ${result.unexpectedEndpoints.length}`); + result.unexpectedEndpoints.forEach(url => { + verboseLog(` • ${url}`); + }); + } + + if (result.error) { + errorLog(` āŒ Error: ${result.error}`); + } + } + + log('\n═══════════════════════════════════════════════════════'); + if (success) { + log('āœ… Discovery Validation: PASSED'); + } else { + errorLog('āŒ Discovery Validation: FAILED'); + } + log('═══════════════════════════════════════════════════════\n'); + + return { + totalFacilitators: facilitators.length, + facilitatorsChecked, + facilitatorResults, + totalExpectedEndpoints: allExpectedEndpoints.length, + totalDiscoveredEndpoints: totalDiscovered, + allEndpointsDiscovered, + success, + }; +} + +/** + * Checks if any servers or facilitators support the bazaar extension + */ +export function shouldRunDiscoveryValidation( + facilitators: Array<{ config: TestConfig }>, + servers: DiscoveredServer[] +): boolean { + const hasServerWithBazaar = servers.some(s => serverSupportsBazaar(s.config)); + const hasFacilitatorWithBazaar = facilitators.some(f => facilitatorSupportsBazaar(f.config)); + + return hasServerWithBazaar && hasFacilitatorWithBazaar; +} + diff --git a/e2e/facilitators/go/README.md b/e2e/facilitators/go/README.md new file mode 100644 index 000000000..a5498c57d --- /dev/null +++ b/e2e/facilitators/go/README.md @@ -0,0 +1,72 @@ +# Go Facilitator for E2E Testing + +This is a real blockchain facilitator implementation using the x402 Go SDK. It connects to Base Sepolia testnet and performs actual on-chain operations. + +## Features + +- **Real EIP-712 Signature Verification**: Uses go-ethereum's apitypes for proper signature recovery and verification +- **Actual Blockchain Calls**: Connects via RPC to read contract state +- **On-Chain Settlement**: Executes real USDC transfers via `transferWithAuthorization` +- **Transaction Monitoring**: Polls for actual transaction receipts + +## Environment Variables + +Required: +- `EVM_PRIVATE_KEY`: The facilitator's private key (must have ETH for gas and USDC for settlements) +- `EVM_NETWORK`: Network identifier (e.g., "eip155:84532" for Base Sepolia) + +Optional: +- `PORT`: HTTP server port (default: 4022) +- `EVM_RPC_URL`: RPC endpoint URL (default: "https://sepolia.base.org") + +## Endpoints + +- `POST /verify`: Verify a payment signature and check nonce state +- `POST /settle`: Execute the payment on-chain +- `GET /supported`: Return supported payment kinds +- `GET /health`: Health check +- `POST /close`: Graceful shutdown + +## Implementation Details + +### Real Blockchain Operations + +#### Signature Verification +- Reconstructs EIP-712 typed data hash +- Recovers signer address from signature +- Compares recovered address with expected payer + +#### Contract Reads +- Calls `authorizationState(address, bytes32)` to check if nonce is used +- Calls `balanceOf(address)` to verify sufficient balance +- Calls `allowance(address, address)` to verify spending approval + +#### Contract Writes +- Creates and signs transactions using the facilitator's private key +- Executes `transferWithAuthorization` on USDC contract +- Waits for transaction confirmation + +### Type Handling + +The facilitator automatically converts between Go types and Ethereum ABI types: +- String addresses → `common.Address` +- Hex string nonces → `[32]byte` +- Separate v, r, s signature components → Single 65-byte signature +- `*big.Int` values → uint256 + +## Running + +```bash +# Make executable +chmod +x run.sh + +# Run with environment variables +EVM_PRIVATE_KEY=0x... EVM_RPC_URL=https://... PORT=4022 ./run.sh +``` + +## Notes + +- The facilitator requires ETH for gas fees on the testnet +- For production, use a reliable RPC endpoint (Alchemy, Infura, etc.) to avoid rate limiting +- The public Base Sepolia RPC may rate limit under heavy load + diff --git a/e2e/facilitators/go/go b/e2e/facilitators/go/go new file mode 100755 index 000000000..fb7fcf26c Binary files /dev/null and b/e2e/facilitators/go/go differ diff --git a/e2e/facilitators/go/go.mod b/e2e/facilitators/go/go.mod new file mode 100644 index 000000000..9e98cc139 --- /dev/null +++ b/e2e/facilitators/go/go.mod @@ -0,0 +1,68 @@ +module github.com/coinbase/x402-go/e2e/facilitators/go + +go 1.23.0 + +toolchain go1.24.1 + +require ( + github.com/coinbase/x402-go/v2 v2.0.0 + github.com/ethereum/go-ethereum v1.13.5 + github.com/gin-gonic/gin v1.11.0 +) + +require ( + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/StackExchange/wmi v1.2.1 // indirect + github.com/bits-and-blooms/bitset v1.7.0 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect + github.com/bytedance/sonic v1.14.0 // indirect + github.com/bytedance/sonic/loader v0.3.0 // indirect + github.com/cloudwego/base64x v0.1.6 // indirect + github.com/consensys/bavard v0.1.13 // indirect + github.com/consensys/gnark-crypto v0.12.1 // indirect + github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect + github.com/deckarep/golang-set/v2 v2.1.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/ethereum/c-kzg-4844 v0.4.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.8 // indirect + github.com/gin-contrib/sse v1.1.0 // indirect + github.com/go-ole/go-ole v1.2.5 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.27.0 // indirect + github.com/go-stack/stack v1.8.1 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/goccy/go-yaml v1.18.0 // indirect + github.com/gorilla/websocket v1.4.2 // indirect + github.com/holiman/uint256 v1.2.4 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mmcloughlin/addchain v0.4.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect + github.com/quic-go/qpack v0.5.1 // indirect + github.com/quic-go/quic-go v0.54.0 // indirect + github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect + github.com/supranational/blst v0.3.11 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.3.0 // indirect + go.uber.org/mock v0.5.0 // indirect + golang.org/x/arch v0.20.0 // indirect + golang.org/x/crypto v0.40.0 // indirect + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect + golang.org/x/mod v0.25.0 // indirect + golang.org/x/net v0.42.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.35.0 // indirect + golang.org/x/text v0.27.0 // indirect + golang.org/x/tools v0.34.0 // indirect + google.golang.org/protobuf v1.36.9 // indirect + rsc.io/tmplfunc v0.0.3 // indirect +) + +replace github.com/coinbase/x402-go/v2 => ../../../go diff --git a/e2e/facilitators/go/go.sum b/e2e/facilitators/go/go.sum new file mode 100644 index 000000000..0da8c6706 --- /dev/null +++ b/e2e/facilitators/go/go.sum @@ -0,0 +1,244 @@ +github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= +github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= +github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= +github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= +github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bits-and-blooms/bitset v1.7.0 h1:YjAGVd3XmtK9ktAbX8Zg2g2PwLIMjGREZJHlV4j7NEo= +github.com/bits-and-blooms/bitset v1.7.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= +github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ= +github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA= +github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= +github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= +github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= +github.com/cockroachdb/errors v1.8.1 h1:A5+txlVZfOqFBDa4mGz2bUWSp0aHElvHX2bKkdbQu+Y= +github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= +github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f h1:o/kfcElHqOiXqcou5a3rIlMc7oJbMQkeLk0VQJ7zgqY= +github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= +github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A= +github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= +github.com/cockroachdb/redact v1.0.8 h1:8QG/764wK+vmEYoOlfobpe12EQcS81ukx/a4hdVMxNw= +github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 h1:IKgmqgMQlVJIZj19CdocBeSfSaiCbEBZGKODaixqtHM= +github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= +github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= +github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= +github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= +github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= +github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= +github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/ethereum/go-ethereum v1.13.5 h1:U6TCRciCqZRe4FPXmy1sMGxTfuk8P7u2UoinF3VbaFk= +github.com/ethereum/go-ethereum v1.13.5/go.mod h1:yMTu38GSuyxaYzQMViqNmQ1s3cE84abZexQmTgenWk0= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= +github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= +github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= +github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= +github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= +github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls= +github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY= +github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= +github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= +github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= +github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= +github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw= +github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= +github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= +github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= +github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= +github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= +github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= +github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= +github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= +github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg= +github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= +github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= +github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= +github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= +github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= +github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= +golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c= +golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= +golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo= +golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= +google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= +google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/e2e/facilitators/go/main.go b/e2e/facilitators/go/main.go new file mode 100644 index 000000000..13d9c2a50 --- /dev/null +++ b/e2e/facilitators/go/main.go @@ -0,0 +1,711 @@ +package main + +import ( + "bytes" + "context" + "crypto/ecdsa" + "encoding/hex" + "encoding/json" + "fmt" + "log" + "math/big" + "net/http" + "os" + "strings" + "time" + + x402 "github.com/coinbase/x402-go/v2" + "github.com/coinbase/x402-go/v2/mechanisms/evm" + evmv1 "github.com/coinbase/x402-go/v2/mechanisms/evm/v1" + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/signer/core/apitypes" + "github.com/gin-gonic/gin" +) + +const ( + DefaultPort = "4022" + Network = "eip155:84532" + Scheme = "exact" +) + +// Request/Response types +type VerifyRequest struct { + X402Version int `json:"x402Version"` + PaymentPayload x402.PaymentPayload `json:"paymentPayload"` + PaymentRequirements x402.PaymentRequirements `json:"paymentRequirements"` +} + +type SettleRequest struct { + X402Version int `json:"x402Version"` + PaymentPayload x402.PaymentPayload `json:"paymentPayload"` + PaymentRequirements x402.PaymentRequirements `json:"paymentRequirements"` +} + +// Real EVM signer for facilitator using ethclient +type realFacilitatorEvmSigner struct { + privateKey *ecdsa.PrivateKey + address common.Address + client *ethclient.Client + chainID *big.Int +} + +func newRealFacilitatorEvmSigner(privateKeyHex string, rpcURL string) (*realFacilitatorEvmSigner, error) { + // Remove 0x prefix if present + privateKeyHex = strings.TrimPrefix(privateKeyHex, "0x") + + privateKey, err := crypto.HexToECDSA(privateKeyHex) + if err != nil { + return nil, fmt.Errorf("failed to parse private key: %w", err) + } + + address := crypto.PubkeyToAddress(privateKey.PublicKey) + + // Connect to blockchain + client, err := ethclient.Dial(rpcURL) + if err != nil { + return nil, fmt.Errorf("failed to connect to RPC: %w", err) + } + + // Get chain ID + ctx := context.Background() + chainID, err := client.ChainID(ctx) + if err != nil { + return nil, fmt.Errorf("failed to get chain ID: %w", err) + } + + return &realFacilitatorEvmSigner{ + privateKey: privateKey, + address: address, + client: client, + chainID: chainID, + }, nil +} + +func (s *realFacilitatorEvmSigner) GetAddress() string { + return s.address.Hex() +} + +func (s *realFacilitatorEvmSigner) GetChainID() (*big.Int, error) { + return s.chainID, nil +} + +func (s *realFacilitatorEvmSigner) VerifyTypedData( + address string, + domain evm.TypedDataDomain, + types map[string][]evm.TypedDataField, + primaryType string, + message map[string]interface{}, + signature []byte, +) (bool, error) { + // Convert to apitypes for EIP-712 verification + chainId := getBigIntFromInterface(domain.ChainID) + typedData := apitypes.TypedData{ + Types: make(apitypes.Types), + PrimaryType: primaryType, + Domain: apitypes.TypedDataDomain{ + Name: getStringFromInterface(domain.Name), + Version: getStringFromInterface(domain.Version), + ChainId: (*math.HexOrDecimal256)(chainId), + VerifyingContract: getStringFromInterface(domain.VerifyingContract), + }, + Message: message, + } + + // Convert types + for typeName, fields := range types { + typedFields := make([]apitypes.Type, len(fields)) + for i, field := range fields { + typedFields[i] = apitypes.Type{ + Name: field.Name, + Type: field.Type, + } + } + typedData.Types[typeName] = typedFields + } + + // Add EIP712Domain if not present + if _, exists := typedData.Types["EIP712Domain"]; !exists { + typedData.Types["EIP712Domain"] = []apitypes.Type{ + {Name: "name", Type: "string"}, + {Name: "version", Type: "string"}, + {Name: "chainId", Type: "uint256"}, + {Name: "verifyingContract", Type: "address"}, + } + } + + // Hash the data + dataHash, err := typedData.HashStruct(typedData.PrimaryType, typedData.Message) + if err != nil { + return false, fmt.Errorf("failed to hash struct: %w", err) + } + + domainSeparator, err := typedData.HashStruct("EIP712Domain", typedData.Domain.Map()) + if err != nil { + return false, fmt.Errorf("failed to hash domain: %w", err) + } + + rawData := []byte{0x19, 0x01} + rawData = append(rawData, domainSeparator...) + rawData = append(rawData, dataHash...) + digest := crypto.Keccak256(rawData) + + // Recover the address from signature + if len(signature) != 65 { + return false, fmt.Errorf("invalid signature length: %d", len(signature)) + } + + // Adjust v value + v := signature[64] + if v >= 27 { + v -= 27 + } + + sigCopy := make([]byte, 65) + copy(sigCopy, signature) + sigCopy[64] = v + + pubKey, err := crypto.SigToPub(digest, sigCopy) + if err != nil { + return false, fmt.Errorf("failed to recover public key: %w", err) + } + + recoveredAddr := crypto.PubkeyToAddress(*pubKey) + expectedAddr := common.HexToAddress(address) + + return bytes.Equal(recoveredAddr.Bytes(), expectedAddr.Bytes()), nil +} + +func (s *realFacilitatorEvmSigner) ReadContract( + contractAddress string, + abiJSON []byte, + method string, + args ...interface{}, +) (interface{}, error) { + // Parse ABI + contractABI, err := abi.JSON(strings.NewReader(string(abiJSON))) + if err != nil { + return nil, fmt.Errorf("failed to parse ABI: %w", err) + } + + // Special handling for methods that expect specific types + processedArgs := make([]interface{}, len(args)) + copy(processedArgs, args) + + switch method { + case "authorizationState": + // authorizationState(address authorizer, bytes32 nonce) returns (bool) + // First argument is the address + if len(processedArgs) > 0 { + if addrStr, ok := processedArgs[0].(string); ok { + processedArgs[0] = common.HexToAddress(addrStr) + } + } + // Second argument is the nonce which needs to be bytes32 + if len(processedArgs) > 1 { + // Check if it's already a [32]byte + if _, ok := processedArgs[1].([32]byte); !ok { + if nonceStr, ok := processedArgs[1].(string); ok { + nonceStr = strings.TrimPrefix(nonceStr, "0x") + nonceBytes, err := hex.DecodeString(nonceStr) + if err != nil { + return nil, fmt.Errorf("failed to decode nonce hex: %w", err) + } + if len(nonceBytes) != 32 { + return nil, fmt.Errorf("nonce must be 32 bytes, got %d", len(nonceBytes)) + } + var nonce32 [32]byte + copy(nonce32[:], nonceBytes) + processedArgs[1] = nonce32 + } + } + } + case "balanceOf", "allowance": + // These methods expect addresses, ensure they're in the right format + for i, arg := range processedArgs { + // Only convert if it's a string (not already a common.Address) + if addrStr, ok := arg.(string); ok { + processedArgs[i] = common.HexToAddress(addrStr) + } + // If it's already a common.Address, leave it as is + } + } + + // Pack the method call + data, err := contractABI.Pack(method, processedArgs...) + if err != nil { + return nil, fmt.Errorf("failed to pack method call: %w", err) + } + + // Make the call + ctx := context.Background() + to := common.HexToAddress(contractAddress) + + // Check if contract exists at this address + code, err := s.client.CodeAt(ctx, to, nil) + if err != nil { + log.Printf("Failed to check contract code: contract=%s, error=%v", contractAddress, err) + } else if len(code) == 0 { + log.Printf("WARNING: No contract code at address %s", contractAddress) + } + + msg := ethereum.CallMsg{ + To: &to, + Data: data, + } + + result, err := s.client.CallContract(ctx, msg, nil) + if err != nil { + log.Printf("Contract call failed: method=%s, contract=%s, error=%v", method, contractAddress, err) + return nil, fmt.Errorf("failed to call contract: %w", err) + } + + log.Printf("Contract call: method=%s, contract=%s, dataLen=%d, resultLen=%d, result=%x", method, contractAddress, len(data), len(result), result) + + // Handle empty result (some contract calls return nothing or revert) + if len(result) == 0 { + // For authorizationState, empty means false (nonce not used) + if method == "authorizationState" { + return false, nil + } + // For balanceOf or allowance, empty might mean 0 + if method == "balanceOf" || method == "allowance" { + return big.NewInt(0), nil + } + return nil, fmt.Errorf("empty result from contract call") + } + + // Unpack the result based on method + method_obj, exists := contractABI.Methods[method] + if !exists { + return nil, fmt.Errorf("method %s not found in ABI", method) + } + + output, err := method_obj.Outputs.Unpack(result) + if err != nil { + return nil, fmt.Errorf("failed to unpack result: %w", err) + } + + // Return the first output (most contract reads return a single value) + if len(output) > 0 { + return output[0], nil + } + + return nil, nil +} + +func (s *realFacilitatorEvmSigner) WriteContract( + contractAddress string, + abiJSON []byte, + method string, + args ...interface{}, +) (string, error) { + // Parse ABI + contractABI, err := abi.JSON(strings.NewReader(string(abiJSON))) + if err != nil { + return "", fmt.Errorf("failed to parse ABI: %w", err) + } + + // Process arguments for special cases + processedArgs := make([]interface{}, len(args)) + copy(processedArgs, args) + + if method == "transferWithAuthorization" { + // transferWithAuthorization expects: + // v1: (address from, address to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 nonce, uint8 v, bytes32 r, bytes32 s) + // Convert string addresses to common.Address + if len(processedArgs) > 0 { + if addrStr, ok := processedArgs[0].(string); ok { + processedArgs[0] = common.HexToAddress(addrStr) + } + } + if len(processedArgs) > 1 { + if addrStr, ok := processedArgs[1].(string); ok { + processedArgs[1] = common.HexToAddress(addrStr) + } + } + + // Ensure nonce is [32]byte (position 5) + if len(processedArgs) > 5 { + if _, ok := processedArgs[5].([32]byte); !ok { + if nonceStr, ok := processedArgs[5].(string); ok { + nonceStr = strings.TrimPrefix(nonceStr, "0x") + nonceBytes, err := hex.DecodeString(nonceStr) + if err != nil { + return "", fmt.Errorf("failed to decode nonce hex: %w", err) + } + if len(nonceBytes) != 32 { + return "", fmt.Errorf("nonce must be 32 bytes, got %d", len(nonceBytes)) + } + var nonce32 [32]byte + copy(nonce32[:], nonceBytes) + processedArgs[5] = nonce32 + } + } + } + // Keep v, r, s as separate arguments (positions 6, 7, 8) for v1 ABI + } + + // Pack the method call + data, err := contractABI.Pack(method, processedArgs...) + if err != nil { + return "", fmt.Errorf("failed to pack method call: %w", err) + } + + // Get nonce + ctx := context.Background() + nonce, err := s.client.PendingNonceAt(ctx, s.address) + if err != nil { + return "", fmt.Errorf("failed to get nonce: %w", err) + } + + // Get gas price + gasPrice, err := s.client.SuggestGasPrice(ctx) + if err != nil { + return "", fmt.Errorf("failed to get gas price: %w", err) + } + + // Create transaction + to := common.HexToAddress(contractAddress) + tx := types.NewTransaction( + nonce, + to, + big.NewInt(0), // value + 300000, // gas limit + gasPrice, + data, + ) + + // Sign transaction + signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(s.chainID), s.privateKey) + if err != nil { + return "", fmt.Errorf("failed to sign transaction: %w", err) + } + + // Send transaction + err = s.client.SendTransaction(ctx, signedTx) + if err != nil { + return "", fmt.Errorf("failed to send transaction: %w", err) + } + + return signedTx.Hash().Hex(), nil +} + +func (s *realFacilitatorEvmSigner) WaitForTransactionReceipt(txHash string) (*evm.TransactionReceipt, error) { + ctx := context.Background() + hash := common.HexToHash(txHash) + + // Poll for receipt + for i := 0; i < 30; i++ { // 30 seconds timeout + receipt, err := s.client.TransactionReceipt(ctx, hash) + if err == nil && receipt != nil { + return &evm.TransactionReceipt{ + Status: uint64(receipt.Status), + BlockNumber: receipt.BlockNumber.Uint64(), + TxHash: receipt.TxHash.Hex(), + }, nil + } + time.Sleep(1 * time.Second) + } + + return nil, fmt.Errorf("transaction receipt not found after 30 seconds") +} + +func (s *realFacilitatorEvmSigner) GetBalance(address string, tokenAddress string) (*big.Int, error) { + if tokenAddress == "" || tokenAddress == "0x0000000000000000000000000000000000000000" { + // Native balance + ctx := context.Background() + balance, err := s.client.BalanceAt(ctx, common.HexToAddress(address), nil) + if err != nil { + return nil, fmt.Errorf("failed to get balance: %w", err) + } + return balance, nil + } + + // ERC20 balance - need to call balanceOf + // Minimal ERC20 ABI for balanceOf + const erc20ABI = `[{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"type":"function"}]` + + // Pass address as string, let ReadContract handle the conversion + result, err := s.ReadContract(tokenAddress, []byte(erc20ABI), "balanceOf", address) + if err != nil { + return nil, err + } + + if balance, ok := result.(*big.Int); ok { + return balance, nil + } + + return nil, fmt.Errorf("unexpected balance type: %T", result) +} + +// Helper functions for type conversion +func getStringFromInterface(v interface{}) string { + if v == nil { + return "" + } + switch val := v.(type) { + case string: + return val + case *string: + if val != nil { + return *val + } + } + return "" +} + +func getBigIntFromInterface(v interface{}) *big.Int { + if v == nil { + return big.NewInt(0) + } + switch val := v.(type) { + case *big.Int: + return val + case int64: + return big.NewInt(val) + case string: + n, _ := new(big.Int).SetString(val, 10) + return n + } + return big.NewInt(0) +} + +func main() { + // Get configuration from environment + port := os.Getenv("PORT") + if port == "" { + port = DefaultPort + } + + evmPrivateKey := os.Getenv("EVM_PRIVATE_KEY") + if evmPrivateKey == "" { + log.Fatal("āŒ EVM_PRIVATE_KEY environment variable is required") + } + + // Get RPC URL from environment, default to Base Sepolia public RPC + rpcURL := os.Getenv("EVM_RPC_URL") + if rpcURL == "" { + rpcURL = "https://sepolia.base.org" + log.Printf("āš ļø Using default RPC URL: %s", rpcURL) + } else { + log.Printf("āœ… Using RPC URL from EVM_RPC_URL: %s", rpcURL) + } + + // Initialize the real blockchain signer + signer, err := newRealFacilitatorEvmSigner(evmPrivateKey, rpcURL) + if err != nil { + log.Fatalf("Failed to create signer: %v", err) + } + + chainID, _ := signer.GetChainID() + log.Printf("Facilitator account: %s", signer.GetAddress()) + log.Printf("Connected to chain ID: %s (expected: 84532 for Base Sepolia)", chainID.String()) + + // Initialize the x402 Facilitator with EVM support + facilitator := x402.Newx402Facilitator() + + // Register the EVM scheme handler for v2 + evmFacilitator := evm.NewExactEvmFacilitator(signer) + facilitator.RegisterScheme(Network, evmFacilitator) + + // Register the EVM v1 scheme handler for base-sepolia + evmFacilitatorV1 := evmv1.NewExactEvmFacilitatorV1(signer) + facilitator.RegisterSchemeV1("base-sepolia", evmFacilitatorV1) + + // Set up Gin router + gin.SetMode(gin.ReleaseMode) + router := gin.New() + router.Use(gin.Recovery()) + + // POST /verify - Verify a payment against requirements + router.POST("/verify", func(c *gin.Context) { + // First, peek at the version to determine which struct to use + var versionCheck struct { + X402Version int `json:"x402Version"` + } + + // Read body into buffer so we can parse it twice + bodyBytes, err := c.GetRawData() + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{ + "error": fmt.Sprintf("Failed to read request body: %v", err), + }) + return + } + + // Parse version + if err := json.Unmarshal(bodyBytes, &versionCheck); err != nil { + c.JSON(http.StatusBadRequest, gin.H{ + "error": fmt.Sprintf("Failed to parse version: %v", err), + }) + return + } + + var req VerifyRequest + if err := json.Unmarshal(bodyBytes, &req); err != nil { + c.JSON(http.StatusBadRequest, gin.H{ + "error": fmt.Sprintf("Invalid request: %v", err), + }) + return + } + + // No transformation needed - v1 mechanisms will read MaxAmountRequired field directly + + response, err := facilitator.Verify( + context.Background(), + req.PaymentPayload, + req.PaymentRequirements, + ) + if err != nil { + log.Printf("Verify error: %v", err) + c.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) + return + } + + c.JSON(http.StatusOK, response) + }) + + // POST /settle - Settle a payment on-chain + router.POST("/settle", func(c *gin.Context) { + // First, peek at the version to determine which struct to use + var versionCheck struct { + X402Version int `json:"x402Version"` + } + + // Read body into buffer so we can parse it twice + bodyBytes, err := c.GetRawData() + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{ + "error": fmt.Sprintf("Failed to read request body: %v", err), + }) + return + } + + // Debug: Log raw request body + log.Printf("šŸ” [FACILITATOR SETTLE] Received raw body: %s", string(bodyBytes)) + + // Parse version + if err := json.Unmarshal(bodyBytes, &versionCheck); err != nil { + c.JSON(http.StatusBadRequest, gin.H{ + "error": fmt.Sprintf("Failed to parse version: %v", err), + }) + return + } + + var req SettleRequest + if err := json.Unmarshal(bodyBytes, &req); err != nil { + c.JSON(http.StatusBadRequest, gin.H{ + "error": fmt.Sprintf("Invalid request: %v", err), + }) + return + } + + // Debug: Log parsed request + log.Printf("šŸ” [FACILITATOR SETTLE] Parsed request:") + log.Printf(" X402Version: %d", req.X402Version) + log.Printf(" PaymentPayload: %+v", req.PaymentPayload) + log.Printf(" PaymentRequirements: %+v", req.PaymentRequirements) + + // No transformation needed - v1 mechanisms will read MaxAmountRequired field directly + + response, err := facilitator.Settle( + context.Background(), + req.PaymentPayload, + req.PaymentRequirements, + ) + + // Debug: Log response + log.Printf("šŸ” [FACILITATOR SETTLE] Response: %+v", response) + log.Printf("šŸ” [FACILITATOR SETTLE] Error: %v", err) + if err != nil { + log.Printf("Settle error: %v", err) + c.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) + return + } + + c.JSON(http.StatusOK, response) + }) + + // GET /supported - Get supported payment kinds and extensions + router.GET("/supported", func(c *gin.Context) { + response := x402.SupportedResponse{ + Kinds: []x402.SupportedKind{ + { + X402Version: 2, + Scheme: Scheme, + Network: Network, + Extra: map[string]interface{}{}, + }, + { + X402Version: 1, + Scheme: Scheme, + Network: "base-sepolia", + Extra: map[string]interface{}{}, + }, + }, + Extensions: []string{}, + } + + c.JSON(http.StatusOK, response) + }) + + // GET /health - Health check endpoint + router.GET("/health", func(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{ + "status": "ok", + "network": Network, + "facilitator": "go", + "version": "2.0.0", + }) + }) + + // POST /close - Graceful shutdown endpoint + router.POST("/close", func(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{ + "message": "Facilitator shutting down gracefully", + }) + log.Println("Received shutdown request") + + // Give time for response to be sent, then exit + go func() { + time.Sleep(100 * time.Millisecond) + os.Exit(0) + }() + }) + + // Start the server + fmt.Printf(` +╔════════════════════════════════════════════════════════╗ +ā•‘ x402 Go Facilitator ā•‘ +╠════════════════════════════════════════════════════════╣ +ā•‘ Server: http://localhost:%s ā•‘ +ā•‘ Network: %s ā•‘ +ā•‘ Address: %s ā•‘ +ā•‘ ā•‘ +ā•‘ Endpoints: ā•‘ +ā•‘ • POST /verify (verify payment) ā•‘ +ā•‘ • POST /settle (settle payment) ā•‘ +ā•‘ • GET /supported (get supported kinds) ā•‘ +ā•‘ • GET /health (health check) ā•‘ +ā•‘ • POST /close (shutdown server) ā•‘ +ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā• +`, port, Network, signer.GetAddress()) + + // Log that facilitator is ready (needed for e2e test discovery) + log.Println("Facilitator listening") + + // Start server + if err := router.Run(":" + port); err != nil { + log.Fatalf("Failed to start server: %v", err) + } +} diff --git a/e2e/facilitators/go/run.sh b/e2e/facilitators/go/run.sh new file mode 100755 index 000000000..5f2f5f850 --- /dev/null +++ b/e2e/facilitators/go/run.sh @@ -0,0 +1,2 @@ +#!/bin/bash +go run main.go diff --git a/e2e/facilitators/go/test.config.json b/e2e/facilitators/go/test.config.json new file mode 100644 index 000000000..e16314677 --- /dev/null +++ b/e2e/facilitators/go/test.config.json @@ -0,0 +1,20 @@ +{ + "name": "go", + "type": "facilitator", + "language": "go", + "protocolFamilies": [ + "evm" + ], + "x402Versions": [ + 2 + ], + "environment": { + "required": [ + "PORT", + "EVM_PRIVATE_KEY" + ], + "optional": [ + "EVM_NETWORK" + ] + } +} \ No newline at end of file diff --git a/e2e/facilitators/text-facilitator-protocol.txt b/e2e/facilitators/text-facilitator-protocol.txt new file mode 100644 index 000000000..ccf6c27e9 --- /dev/null +++ b/e2e/facilitators/text-facilitator-protocol.txt @@ -0,0 +1,169 @@ +# X402 Facilitator Protocol + +## CLI Interface +1. Must be runnable through a CLI command, which can be parsed from 'run.sh' +2. Must output specific logs +3. Must exit with code 0 for success, 1 for failure +4. Must run as a server listening on a specified port + +## Protocol Family Support +Facilitators must declare which protocol families they support in their test.config.json: +- **EVM**: Ethereum Virtual Machine compatible networks (Base, Ethereum, etc.) +- **SVM**: Solana Virtual Machine compatible networks (Solana, etc.) + +## X402 Version Support +Facilitators must declare which x402 protocol versions they support using the `x402Versions` field: +- **x402Versions**: Array of supported x402 protocol versions (e.g., [1, 2]) + +## Extensions Support +Facilitators must declare which protocol extensions they support using the `extensions` field: +- **extensions**: Array of supported extension names (e.g., ["bazaar"]) + +Example configuration: +```json +{ + "name": "typescript", + "type": "facilitator", + "language": "typescript", + "protocolFamilies": ["evm"], + "x402Versions": [2], + "extensions": ["bazaar"], + "environment": { + "required": ["PORT", "EVM_PRIVATE_KEY", "EVM_NETWORK"], + "optional": ["SVM_PRIVATE_KEY", "SVM_NETWORK"] + } +} +``` + +## Environment Variables / CLI Arguments +The following parameters must be configurable: +- `PORT`: Port to listen on (default: 4022) +- `EVM_PRIVATE_KEY`: Private key for EVM operations +- `SVM_PRIVATE_KEY`: Private key for Solana operations +- `EVM_NETWORK`: EVM network to use (e.g., "eip155:84532" for Base Sepolia) +- `SVM_NETWORK`: Solana network to use (e.g., "solana:devnet") + +## Required Endpoints + +### POST /verify +- **Purpose**: Verify a payment against requirements +- **Request Body**: + ```json + { + "x402Version": 2, + "paymentPayload": { + "x402Version": 2, + "scheme": "exact", + "network": "eip155:84532", + "payload": { ... }, + "accepted": { ... } + }, + "paymentRequirements": { + "scheme": "exact", + "network": "eip155:84532", + "asset": "erc20:0x...", + "amount": "1000000", + "payTo": "0x...", + "extra": { ... } + } + } + ``` +- **Success Response (200)**: + ```json + { + "isValid": true, + "payer": "0x..." + } + ``` +- **Invalid Response (200)**: + ```json + { + "isValid": false, + "invalidReason": "Invalid signature", + "payer": "0x..." + } + ``` + +### POST /settle +- **Purpose**: Settle a payment on-chain +- **Request Body**: Same as /verify +- **Success Response (200)**: + ```json + { + "success": true, + "transaction": "0x...", + "network": "eip155:84532", + "payer": "0x..." + } + ``` +- **Failure Response (200)**: + ```json + { + "success": false, + "errorReason": "Settlement failed", + "network": "eip155:84532" + } + ``` + +### GET /supported +- **Purpose**: Get supported payment kinds and extensions +- **Response (200)**: + ```json + { + "kinds": [ + { + "x402Version": 2, + "scheme": "exact", + "network": "eip155:84532", + "extra": {} + } + ], + "extensions": ["bazaar"] + } + ``` + +### GET /discovery/resources +- **Purpose**: List all discovered resources from bazaar extensions +- **Query Parameters**: + - `limit` (optional): Maximum number of resources to return (default: 100) + - `offset` (optional): Offset for pagination (default: 0) +- **Response (200)**: + ```json + { + "x402Version": 1, + "items": [ + { + "resource": "https://api.example.com/endpoint", + "type": "http", + "x402Version": 2, + "accepts": [...], + "discoveryInfo": {...}, + "lastUpdated": "2024-01-01T00:00:00Z", + "metadata": {} + } + ], + "pagination": { + "limit": 100, + "offset": 0, + "total": 1 + } + } + ``` + +### GET /health +- **Purpose**: Health check endpoint +- **Response (200)**: + ```json + { + "status": "ok" + } + ``` + +### POST /close +- **Purpose**: Gracefully shut down the facilitator +- **Response**: Should terminate the process with exit code 0 + +## Startup Requirements +- Must log "Facilitator listening" when ready to accept requests +- Must handle graceful shutdown on SIGTERM/SIGINT +- Must validate required environment variables on startup diff --git a/e2e/facilitators/typescript/index.ts b/e2e/facilitators/typescript/index.ts new file mode 100644 index 000000000..7b37ddfe5 --- /dev/null +++ b/e2e/facilitators/typescript/index.ts @@ -0,0 +1,378 @@ +/** + * TypeScript Facilitator for E2E Testing + * + * This facilitator provides HTTP endpoints for payment verification and settlement + * using the x402 TypeScript SDK. + * + * Features: + * - Payment verification and settlement + * - Bazaar discovery extension support + * - Verified payment tracking (verify → settle flow) + * - Discovery resource cataloging + */ + +import express from "express"; +import { x402Facilitator } from "@x402/core/facilitator"; +import { + PaymentPayload, + PaymentRequirements, + VerifyResponse, + SettleResponse, + SupportedResponse, +} from "@x402/core/types"; +import { ExactEvmFacilitator, toFacilitatorEvmSigner } from "@x402/evm"; +import { createWalletClient, http, publicActions } from "viem"; +import { privateKeyToAccount } from "viem/accounts"; +import { baseSepolia } from "viem/chains"; +import dotenv from "dotenv"; +import { ExactEvmFacilitatorV1 } from "@x402/evm/v1"; +import { + BAZAAR, + extractDiscoveryInfo, + type DiscoveryInfo, +} from "@x402/extensions/bazaar"; +import crypto from "crypto"; + +dotenv.config(); + +// Configuration +const PORT = process.env.PORT || "4022"; + +// Validate required environment variables +if (!process.env.EVM_PRIVATE_KEY) { + console.error("āŒ EVM_PRIVATE_KEY environment variable is required"); + process.exit(1); +} + +// Initialize the EVM account from private key +const account = privateKeyToAccount(process.env.EVM_PRIVATE_KEY as `0x${string}`); +console.info(`Facilitator account: ${account.address}`); + +// Create a Viem client with both wallet and public capabilities +const viemClient = createWalletClient({ + account, + chain: baseSepolia, + transport: http(), +}).extend(publicActions); + +// Initialize the x402 Facilitator with EVM support + +const signer = toFacilitatorEvmSigner({ + readContract: (args: { + address: `0x${string}`; + abi: readonly unknown[]; + functionName: string; + args?: readonly unknown[]; + }) => + viemClient.readContract({ + ...args, + args: args.args || [], + }), + verifyTypedData: (args: { + address: `0x${string}`; + domain: Record; + types: Record; + primaryType: string; + message: Record; + signature: `0x${string}`; + }) => viemClient.verifyTypedData(args as any), + writeContract: (args: { + address: `0x${string}`; + abi: readonly unknown[]; + functionName: string; + args: readonly unknown[]; + }) => + viemClient.writeContract({ + ...args, + args: args.args || [], + }), + waitForTransactionReceipt: (args: { hash: `0x${string}` }) => + viemClient.waitForTransactionReceipt(args), +}); + +// Register the EVM scheme handler for v2 +const facilitator = new x402Facilitator() + .registerScheme( + "eip155:*", + new ExactEvmFacilitator( + signer + ) + ) + .registerSchemeV1("base-sepolia" as `${string}:${string}`, new ExactEvmFacilitatorV1(signer)) + .registerExtension(BAZAAR); + +/** + * Verified Payments Tracking + * Maps payment hash → timestamp for verify → settle flow validation + */ +const verifiedPayments = new Map(); + +/** + * Discovery Resources Storage + * Stores discovered resources from bazaar extensions + */ +interface DiscoveredResource { + resource: string; + type: "http"; + x402Version: number; + accepts: PaymentRequirements[]; + discoveryInfo?: DiscoveryInfo; + lastUpdated: string; + metadata?: Record; +} + +const discoveredResources = new Map(); + +/** + * Helper to create a payment hash for tracking + */ +function createPaymentHash(paymentPayload: PaymentPayload): string { + return crypto + .createHash("sha256") + .update(JSON.stringify(paymentPayload)) + .digest("hex"); +} + +// Initialize Express app +const app = express(); +app.use(express.json()); + +/** + * POST /verify + * Verify a payment against requirements + * + * Also tracks verified payments and extracts bazaar discovery info + */ +app.post("/verify", async (req, res) => { + try { + const { paymentPayload, paymentRequirements } = req.body; + + if (!paymentPayload || !paymentRequirements) { + return res.status(400).json({ + error: "Missing paymentPayload or paymentRequirements", + }); + } + + const response: VerifyResponse = await facilitator.verify( + paymentPayload as PaymentPayload, + paymentRequirements as PaymentRequirements, + ); + + // Track verified payment for settle validation + if (response.isValid) { + const paymentHash = createPaymentHash(paymentPayload); + verifiedPayments.set(paymentHash, Date.now()); + + // Extract and store discovery info if present + // For v2: extensions are in paymentPayload.extensions (client copied from PaymentRequired) + // For v1: discovery info is in paymentRequirements.outputSchema + const discoveryInfo = extractDiscoveryInfo( + paymentPayload, + paymentRequirements + ); + + if (discoveryInfo) { + // Try to get resource URL from various sources + const resourceUrl = + paymentRequirements.extra?.resourceUrl || + (paymentRequirements as any).resource || // v1 has resource field + `http://unknown${discoveryInfo.input.method === 'GET' ? '/get' : '/post'}`; + + console.log(`šŸ“ Discovered resource: ${resourceUrl}`); + console.log(` Method: ${discoveryInfo.input.method}`); + console.log(` x402 Version: ${paymentPayload.x402Version}`); + + discoveredResources.set(resourceUrl, { + resource: resourceUrl, + type: "http", + x402Version: paymentPayload.x402Version, + accepts: [paymentRequirements], + discoveryInfo, + lastUpdated: new Date().toISOString(), + metadata: {}, + }); + } + } + + res.json(response); + } catch (error) { + console.error("Verify error:", error); + res.status(500).json({ + error: error instanceof Error ? error.message : "Unknown error", + }); + } +}); + +/** + * POST /settle + * Settle a payment on-chain + * + * Validates that the payment was previously verified + */ +app.post("/settle", async (req, res) => { + try { + const { paymentPayload, paymentRequirements } = req.body; + + if (!paymentPayload || !paymentRequirements) { + return res.status(400).json({ + error: "Missing paymentPayload or paymentRequirements", + }); + } + + // Validate that payment was previously verified + const paymentHash = createPaymentHash(paymentPayload); + const verificationTimestamp = verifiedPayments.get(paymentHash); + + if (!verificationTimestamp) { + return res.json({ + success: false, + errorReason: "Payment must be verified before settlement", + network: paymentPayload.network, + } as SettleResponse); + } + + // Check verification isn't too old (5 minute timeout) + const age = Date.now() - verificationTimestamp; + if (age > 5 * 60 * 1000) { + verifiedPayments.delete(paymentHash); + return res.json({ + success: false, + errorReason: "Payment verification expired (must settle within 5 minutes)", + network: paymentPayload.network, + } as SettleResponse); + } + + // No transformation needed - v1 mechanisms will read maxAmountRequired field directly + const response: SettleResponse = await facilitator.settle( + paymentPayload as PaymentPayload, + paymentRequirements as PaymentRequirements, + ); + + // Clean up verified payment after settlement (successful or not) + verifiedPayments.delete(paymentHash); + + res.json(response); + } catch (error) { + console.error("Settle error:", error); + res.status(500).json({ + error: error instanceof Error ? error.message : "Unknown error", + }); + } +}); + +/** + * GET /supported + * Get supported payment kinds and extensions + */ +app.get("/supported", async (req, res) => { + try { + const response: SupportedResponse = { + kinds: [ + { + x402Version: 2, + scheme: "exact", + network: "eip155:84532", + extra: {}, + }, + { + x402Version: 1, + scheme: "exact", + network: "base-sepolia" as `${string}:${string}`, + extra: {}, + }, + ], + extensions: [BAZAAR], + }; + + res.json(response); + } catch (error) { + console.error("Supported error:", error); + res.status(500).json({ + error: error instanceof Error ? error.message : "Unknown error", + }); + } +}); + +/** + * GET /discovery/resources + * List all discovered resources from bazaar extensions + */ +app.get("/discovery/resources", (req, res) => { + try { + const limit = parseInt(req.query.limit as string) || 100; + const offset = parseInt(req.query.offset as string) || 0; + + const allResources = Array.from(discoveredResources.values()); + const total = allResources.length; + const items = allResources.slice(offset, offset + limit); + + res.json({ + x402Version: 1, + items, + pagination: { + limit, + offset, + total, + }, + }); + } catch (error) { + console.error("Discovery resources error:", error); + res.status(500).json({ + error: error instanceof Error ? error.message : "Unknown error", + }); + } +}); + +/** + * GET /health + * Health check endpoint + */ +app.get("/health", (req, res) => { + res.json({ + status: "ok", + network: "eip155:84532", + facilitator: "typescript", + version: "2.0.0", + extensions: [BAZAAR], + discoveredResources: discoveredResources.size, + }); +}); + +/** + * POST /close + * Graceful shutdown endpoint + */ +app.post("/close", (req, res) => { + res.json({ message: "Facilitator shutting down gracefully" }); + console.log("Received shutdown request"); + + // Give time for response to be sent + setTimeout(() => { + process.exit(0); + }, 100); +}); + +// Start the server +app.listen(parseInt(PORT), () => { + console.log(` +╔════════════════════════════════════════════════════════╗ +ā•‘ x402 TypeScript Facilitator ā•‘ +╠════════════════════════════════════════════════════════╣ +ā•‘ Server: http://localhost:${PORT} ā•‘ +ā•‘ Network: eip155:84532 ā•‘ +ā•‘ Address: ${account.address} ā•‘ +ā•‘ Extensions: bazaar ā•‘ +ā•‘ ā•‘ +ā•‘ Endpoints: ā•‘ +ā•‘ • POST /verify (verify payment) ā•‘ +ā•‘ • POST /settle (settle payment) ā•‘ +ā•‘ • GET /supported (get supported kinds) ā•‘ +ā•‘ • GET /discovery/resources (list discovered) ā•‘ +ā•‘ • GET /health (health check) ā•‘ +ā•‘ • POST /close (shutdown server) ā•‘ +ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā• + `); + + // Log that facilitator is ready (needed for e2e test discovery) + console.log("Facilitator listening"); +}); diff --git a/e2e/facilitators/typescript/package.json b/e2e/facilitators/typescript/package.json new file mode 100644 index 000000000..7d4b43fbf --- /dev/null +++ b/e2e/facilitators/typescript/package.json @@ -0,0 +1,30 @@ +{ + "name": "@x402/e2e-facilitator-typescript", + "version": "2.0.0", + "type": "module", + "private": true, + "scripts": { + "start": "tsx index.ts", + "dev": "tsx watch index.ts", + "build": "tsc", + "lint": "eslint .", + "format": "prettier --write .", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@x402/core": "workspace:*", + "@x402/evm": "workspace:*", + "@x402/extensions": "workspace:*", + "dotenv": "^16.4.5", + "express": "^4.19.2", + "viem": "^2.21.54" + }, + "devDependencies": { + "@types/express": "^4.17.21", + "@types/node": "^22.10.1", + "eslint": "^9.15.0", + "prettier": "^3.3.3", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + } +} \ No newline at end of file diff --git a/e2e/facilitators/typescript/run.sh b/e2e/facilitators/typescript/run.sh new file mode 100755 index 000000000..2864b3a7e --- /dev/null +++ b/e2e/facilitators/typescript/run.sh @@ -0,0 +1,2 @@ +#!/bin/bash +pnpm start diff --git a/e2e/facilitators/typescript/test.config.json b/e2e/facilitators/typescript/test.config.json new file mode 100644 index 000000000..7a5993186 --- /dev/null +++ b/e2e/facilitators/typescript/test.config.json @@ -0,0 +1,23 @@ +{ + "name": "typescript", + "type": "facilitator", + "language": "typescript", + "protocolFamilies": [ + "evm" + ], + "x402Versions": [ + 2 + ], + "extensions": [ + "bazaar" + ], + "environment": { + "required": [ + "PORT", + "EVM_PRIVATE_KEY" + ], + "optional": [ + "EVM_NETWORK" + ] + } +} \ No newline at end of file diff --git a/e2e/facilitators/typescript/tsconfig.json b/e2e/facilitators/typescript/tsconfig.json new file mode 100644 index 000000000..e85a5d7c2 --- /dev/null +++ b/e2e/facilitators/typescript/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "lib": [ + "ES2022" + ], + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "outDir": "./dist" + }, + "include": [ + "*.ts" + ], + "exclude": [ + "node_modules", + "dist" + ] +} \ No newline at end of file diff --git a/e2e/clients/axios/.env-local b/e2e/legacy/clients/axios/.env-local similarity index 100% rename from e2e/clients/axios/.env-local rename to e2e/legacy/clients/axios/.env-local diff --git a/e2e/clients/axios/.prettierignore b/e2e/legacy/clients/axios/.prettierignore similarity index 100% rename from e2e/clients/axios/.prettierignore rename to e2e/legacy/clients/axios/.prettierignore diff --git a/e2e/clients/axios/.prettierrc b/e2e/legacy/clients/axios/.prettierrc similarity index 100% rename from e2e/clients/axios/.prettierrc rename to e2e/legacy/clients/axios/.prettierrc diff --git a/e2e/clients/axios/README.md b/e2e/legacy/clients/axios/README.md similarity index 100% rename from e2e/clients/axios/README.md rename to e2e/legacy/clients/axios/README.md diff --git a/e2e/clients/axios/eslint.config.js b/e2e/legacy/clients/axios/eslint.config.js similarity index 100% rename from e2e/clients/axios/eslint.config.js rename to e2e/legacy/clients/axios/eslint.config.js diff --git a/e2e/clients/axios/index.ts b/e2e/legacy/clients/axios/index.ts similarity index 100% rename from e2e/clients/axios/index.ts rename to e2e/legacy/clients/axios/index.ts diff --git a/e2e/clients/axios/package.json b/e2e/legacy/clients/axios/package.json similarity index 100% rename from e2e/clients/axios/package.json rename to e2e/legacy/clients/axios/package.json diff --git a/e2e/clients/axios/run.sh b/e2e/legacy/clients/axios/run.sh similarity index 100% rename from e2e/clients/axios/run.sh rename to e2e/legacy/clients/axios/run.sh diff --git a/e2e/clients/axios/test.config.json b/e2e/legacy/clients/axios/test.config.json similarity index 90% rename from e2e/clients/axios/test.config.json rename to e2e/legacy/clients/axios/test.config.json index c94ad046b..06c16dad4 100644 --- a/e2e/clients/axios/test.config.json +++ b/e2e/legacy/clients/axios/test.config.json @@ -6,6 +6,9 @@ "evm", "svm" ], + "x402Versions": [ + 1 + ], "environment": { "required": [ "EVM_PRIVATE_KEY", diff --git a/e2e/clients/axios/tsconfig.json b/e2e/legacy/clients/axios/tsconfig.json similarity index 100% rename from e2e/clients/axios/tsconfig.json rename to e2e/legacy/clients/axios/tsconfig.json diff --git a/e2e/legacy/clients/fetch/.env-local b/e2e/legacy/clients/fetch/.env-local new file mode 100644 index 000000000..571d0bcf6 --- /dev/null +++ b/e2e/legacy/clients/fetch/.env-local @@ -0,0 +1,4 @@ +RESOURCE_SERVER_URL=http://localhost:4021 +ENDPOINT_PATH=/weather +EVM_PRIVATE_KEY= +SVM_PRIVATE_KEY= diff --git a/e2e/servers/hono/.prettierignore b/e2e/legacy/clients/fetch/.prettierignore similarity index 100% rename from e2e/servers/hono/.prettierignore rename to e2e/legacy/clients/fetch/.prettierignore diff --git a/e2e/servers/hono/.prettierrc b/e2e/legacy/clients/fetch/.prettierrc similarity index 100% rename from e2e/servers/hono/.prettierrc rename to e2e/legacy/clients/fetch/.prettierrc diff --git a/examples/typescript/clients/fetch/README.md b/e2e/legacy/clients/fetch/README.md similarity index 100% rename from examples/typescript/clients/fetch/README.md rename to e2e/legacy/clients/fetch/README.md diff --git a/examples/typescript/agent/eslint.config.js b/e2e/legacy/clients/fetch/eslint.config.js similarity index 100% rename from examples/typescript/agent/eslint.config.js rename to e2e/legacy/clients/fetch/eslint.config.js diff --git a/e2e/legacy/clients/fetch/index.ts b/e2e/legacy/clients/fetch/index.ts new file mode 100644 index 000000000..e7625705a --- /dev/null +++ b/e2e/legacy/clients/fetch/index.ts @@ -0,0 +1,51 @@ +import { config } from "dotenv"; +import { Hex } from "viem"; +import { createSigner, decodeXPaymentResponse, MultiNetworkSigner, wrapFetchWithPayment } from "x402-fetch"; + +config(); + +const evmPrivateKey = process.env.EVM_PRIVATE_KEY as Hex; +const svmPrivateKey = process.env.SVM_PRIVATE_KEY as string; +const baseURL = process.env.RESOURCE_SERVER_URL as string; +const endpointPath = process.env.ENDPOINT_PATH as string; +const url = `${baseURL}${endpointPath}`; + +if (!baseURL || !evmPrivateKey || !svmPrivateKey || !endpointPath) { + console.error("Missing required environment variables"); + process.exit(1); +} + +const evmSigner = await createSigner("base-sepolia", evmPrivateKey); +const svmSigner = await createSigner("solana-devnet", svmPrivateKey); +const account = { evm: evmSigner, svm: svmSigner } as MultiNetworkSigner; + +const fetchWithPayment = wrapFetchWithPayment(fetch, account); + +fetchWithPayment(url, { + method: "GET", +}) + .then(async response => { + const data = await response.json(); + const paymentResponse = response.headers.get("x-payment-response"); + + const result = { + success: true, + data: data, + status_code: response.status, + payment_response: decodeXPaymentResponse(paymentResponse!) + }; + + // Output structured result as JSON for proxy to parse + console.log(JSON.stringify(result)); + process.exit(0); + }) + .catch(error => { + const errorResult = { + success: false, + error: error.message || String(error), + status_code: error.response?.status + }; + + console.log(JSON.stringify(errorResult)); + process.exit(1); + }); diff --git a/e2e/legacy/clients/fetch/package.json b/e2e/legacy/clients/fetch/package.json new file mode 100644 index 000000000..f079ea58f --- /dev/null +++ b/e2e/legacy/clients/fetch/package.json @@ -0,0 +1,30 @@ +{ + "name": "fetch-client-example", + "private": true, + "type": "module", + "scripts": { + "dev": "tsx index.ts", + "format": "prettier -c .prettierrc --write \"**/*.{ts,js,cjs,json,md}\"", + "format:check": "prettier -c .prettierrc --check \"**/*.{ts,js,cjs,json,md}\"", + "lint": "eslint . --ext .ts --fix", + "lint:check": "eslint . --ext .ts" + }, + "dependencies": { + "axios": "^1.7.9", + "dotenv": "^16.4.7", + "viem": "^2.21.26", + "x402-fetch": "workspace:*" + }, + "devDependencies": { + "@eslint/js": "^9.24.0", + "eslint": "^9.24.0", + "eslint-plugin-jsdoc": "^50.6.9", + "eslint-plugin-prettier": "^5.2.6", + "@typescript-eslint/eslint-plugin": "^8.29.1", + "@typescript-eslint/parser": "^8.29.1", + "eslint-plugin-import": "^2.31.0", + "prettier": "3.5.2", + "tsx": "^4.7.0", + "typescript": "^5.3.0" + } +} diff --git a/e2e/servers/hono/run.sh b/e2e/legacy/clients/fetch/run.sh similarity index 100% rename from e2e/servers/hono/run.sh rename to e2e/legacy/clients/fetch/run.sh diff --git a/e2e/legacy/clients/fetch/test.config.json b/e2e/legacy/clients/fetch/test.config.json new file mode 100644 index 000000000..792d2c146 --- /dev/null +++ b/e2e/legacy/clients/fetch/test.config.json @@ -0,0 +1,21 @@ +{ + "name": "fetch", + "type": "client", + "language": "typescript", + "protocolFamilies": [ + "evm", + "svm" + ], + "x402Versions": [ + 1 + ], + "environment": { + "required": [ + "EVM_PRIVATE_KEY", + "SVM_PRIVATE_KEY", + "RESOURCE_SERVER_URL", + "ENDPOINT_PATH" + ], + "optional": [] + } +} \ No newline at end of file diff --git a/e2e/legacy/clients/fetch/tsconfig.json b/e2e/legacy/clients/fetch/tsconfig.json new file mode 100644 index 000000000..81e0e7f1f --- /dev/null +++ b/e2e/legacy/clients/fetch/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ES2022", + "moduleResolution": "bundler", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "skipLibCheck": true, + "strict": true, + "resolveJsonModule": true, + "baseUrl": ".", + "types": [ + "node" + ] + }, + "include": [ + "index.ts" + ] +} \ No newline at end of file diff --git a/e2e/clients/httpx/main.py b/e2e/legacy/clients/httpx/main.py similarity index 81% rename from e2e/clients/httpx/main.py rename to e2e/legacy/clients/httpx/main.py index c5dbe726d..a13d8ccab 100644 --- a/e2e/clients/httpx/main.py +++ b/e2e/legacy/clients/httpx/main.py @@ -25,10 +25,12 @@ async def main(): - # Create httpx client with x402 payment hooks - async with httpx.AsyncClient(base_url=base_url) as client: - # Add payment hooks directly to client.event_hooks - client.event_hooks = x402_payment_hooks(account) + # Create httpx client with x402 payment hooks and increased timeout + # Set timeout to 30 seconds to handle busy servers during test runs + timeout = httpx.Timeout(30.0, connect=10.0) + async with httpx.AsyncClient(base_url=base_url, timeout=timeout) as client: + # Add payment hooks directly to client.event_hooks, passing client reference for proper retries + client.event_hooks = x402_payment_hooks(account, httpx_client=client) # Make request try: diff --git a/e2e/clients/httpx/pyproject.toml b/e2e/legacy/clients/httpx/pyproject.toml similarity index 88% rename from e2e/clients/httpx/pyproject.toml rename to e2e/legacy/clients/httpx/pyproject.toml index 6485e2902..0e68fc429 100644 --- a/e2e/clients/httpx/pyproject.toml +++ b/e2e/legacy/clients/httpx/pyproject.toml @@ -24,4 +24,4 @@ allow-direct-references = true package = false [tool.uv.sources] -x402 = { path = "../../../python/x402", editable = true } \ No newline at end of file +x402 = { path = "../../../../python/x402", editable = true } \ No newline at end of file diff --git a/e2e/clients/httpx/run.sh b/e2e/legacy/clients/httpx/run.sh similarity index 100% rename from e2e/clients/httpx/run.sh rename to e2e/legacy/clients/httpx/run.sh diff --git a/e2e/clients/httpx/test.config.json b/e2e/legacy/clients/httpx/test.config.json similarity index 90% rename from e2e/clients/httpx/test.config.json rename to e2e/legacy/clients/httpx/test.config.json index 0a5616452..736aaaf42 100644 --- a/e2e/clients/httpx/test.config.json +++ b/e2e/legacy/clients/httpx/test.config.json @@ -5,6 +5,9 @@ "protocolFamilies": [ "evm" ], + "x402Versions": [ + 1 + ], "description": "Python httpx client with x402 payment hooks", "environment": { "required": [ diff --git a/e2e/clients/httpx/uv.lock b/e2e/legacy/clients/httpx/uv.lock similarity index 99% rename from e2e/clients/httpx/uv.lock rename to e2e/legacy/clients/httpx/uv.lock index 32867d5c5..f2124e12d 100644 --- a/e2e/clients/httpx/uv.lock +++ b/e2e/legacy/clients/httpx/uv.lock @@ -1863,7 +1863,7 @@ wheels = [ [[package]] name = "x402" version = "0.2.1" -source = { editable = "../../../python/x402" } +source = { editable = "../../../../python/x402" } dependencies = [ { name = "eth-account" }, { name = "eth-typing" }, @@ -1912,7 +1912,7 @@ requires-dist = [ { name = "eth-account", specifier = ">=0.8.0" }, { name = "httpx", specifier = ">=0.24.0" }, { name = "python-dotenv", specifier = ">=1.0.0" }, - { name = "x402", editable = "../../../python/x402" }, + { name = "x402", editable = "../../../../python/x402" }, ] [[package]] diff --git a/e2e/clients/requests/main.py b/e2e/legacy/clients/requests/main.py similarity index 100% rename from e2e/clients/requests/main.py rename to e2e/legacy/clients/requests/main.py diff --git a/e2e/clients/requests/pyproject.toml b/e2e/legacy/clients/requests/pyproject.toml similarity index 88% rename from e2e/clients/requests/pyproject.toml rename to e2e/legacy/clients/requests/pyproject.toml index 37c46fedf..2e426f833 100644 --- a/e2e/clients/requests/pyproject.toml +++ b/e2e/legacy/clients/requests/pyproject.toml @@ -24,4 +24,4 @@ allow-direct-references = true package = false [tool.uv.sources] -x402 = { path = "../../../python/x402", editable = true } \ No newline at end of file +x402 = { path = "../../../../python/x402", editable = true } \ No newline at end of file diff --git a/e2e/clients/requests/run.sh b/e2e/legacy/clients/requests/run.sh similarity index 100% rename from e2e/clients/requests/run.sh rename to e2e/legacy/clients/requests/run.sh diff --git a/e2e/clients/requests/test.config.json b/e2e/legacy/clients/requests/test.config.json similarity index 91% rename from e2e/clients/requests/test.config.json rename to e2e/legacy/clients/requests/test.config.json index 4cd52ead5..53138f718 100644 --- a/e2e/clients/requests/test.config.json +++ b/e2e/legacy/clients/requests/test.config.json @@ -5,6 +5,9 @@ "protocolFamilies": [ "evm" ], + "x402Versions": [ + 1 + ], "description": "Python requests client with x402 HTTP adapter", "environment": { "required": [ diff --git a/e2e/clients/requests/uv.lock b/e2e/legacy/clients/requests/uv.lock similarity index 99% rename from e2e/clients/requests/uv.lock rename to e2e/legacy/clients/requests/uv.lock index d8dc6c899..39564a65f 100644 --- a/e2e/clients/requests/uv.lock +++ b/e2e/legacy/clients/requests/uv.lock @@ -1863,7 +1863,7 @@ wheels = [ [[package]] name = "x402" version = "0.2.1" -source = { editable = "../../../python/x402" } +source = { editable = "../../../../python/x402" } dependencies = [ { name = "eth-account" }, { name = "eth-typing" }, @@ -1912,7 +1912,7 @@ requires-dist = [ { name = "eth-account", specifier = ">=0.8.0" }, { name = "python-dotenv", specifier = ">=1.0.0" }, { name = "requests", specifier = ">=2.31.0" }, - { name = "x402", editable = "../../../python/x402" }, + { name = "x402", editable = "../../../../python/x402" }, ] [[package]] diff --git a/e2e/legacy/servers/express/.env-local b/e2e/legacy/servers/express/.env-local new file mode 100644 index 000000000..043fec0ae --- /dev/null +++ b/e2e/legacy/servers/express/.env-local @@ -0,0 +1,9 @@ +FACILITATOR_URL=https://x402.org/facilitator +EVM_NETWORK=base-sepolia +SVM_NETWORK=solana-devnet +EVM_ADDRESS= +SVM_ADDRESS= + +# required if using the Base mainnet facilitator +CDP_API_KEY_ID="Coinbase Developer Platform Key" +CDP_API_KEY_SECRET="Coinbase Developer Platform Key Secret" \ No newline at end of file diff --git a/e2e/servers/next/.prettierignore b/e2e/legacy/servers/express/.prettierignore similarity index 100% rename from e2e/servers/next/.prettierignore rename to e2e/legacy/servers/express/.prettierignore diff --git a/e2e/servers/next/.prettierrc b/e2e/legacy/servers/express/.prettierrc similarity index 100% rename from e2e/servers/next/.prettierrc rename to e2e/legacy/servers/express/.prettierrc diff --git a/examples/typescript/servers/express/README.md b/e2e/legacy/servers/express/README.md similarity index 100% rename from examples/typescript/servers/express/README.md rename to e2e/legacy/servers/express/README.md diff --git a/e2e/servers/hono/eslint.config.js b/e2e/legacy/servers/express/eslint.config.js similarity index 100% rename from e2e/servers/hono/eslint.config.js rename to e2e/legacy/servers/express/eslint.config.js diff --git a/e2e/legacy/servers/express/index.ts b/e2e/legacy/servers/express/index.ts new file mode 100644 index 000000000..baeb7381b --- /dev/null +++ b/e2e/legacy/servers/express/index.ts @@ -0,0 +1,84 @@ +import express from "express"; +import { Network, paymentMiddleware, SolanaAddress } from "x402-express"; +import dotenv from "dotenv"; + +dotenv.config(); + +const evmNetwork = process.env.EVM_NETWORK as Network; +const svmNetwork = process.env.SVM_NETWORK as Network; +const payToEvm = process.env.EVM_ADDRESS as `0x${string}`; +const payToSvm = process.env.SVM_ADDRESS as SolanaAddress; +const port = process.env.PORT || "4021"; +const facilitatorUrl = process.env.FACILITATOR_URL; + +if (!payToEvm || !evmNetwork) { + console.error("Missing required environment variables"); + process.exit(1); +} + +// Create facilitator config if URL is provided +const facilitatorConfig = facilitatorUrl + ? { url: facilitatorUrl as `${string}://${string}` } + : undefined as any; + +if (facilitatorUrl) { + console.log(`Using remote facilitator at: ${facilitatorUrl}`); +} else { + console.log(`Using default facilitator`); +} + +const app = express(); + +app.use( + paymentMiddleware( + payToEvm, + { + "GET /protected": { + price: "$0.001", + network: evmNetwork, + }, + }, + facilitatorConfig + ), +); + +app.use( + paymentMiddleware( + payToSvm, + { + "GET /protected-svm": { + price: "$0.001", + network: svmNetwork, + }, + }, + facilitatorConfig + ), +); + +app.get("/protected", (req, res) => { + res.json({ + message: "Protected endpoint accessed successfully", + timestamp: new Date().toISOString(), + }); +}); + +app.get("/protected-svm", (req, res) => { + res.json({ + message: "Protected endpoint #2 accessed successfully", + timestamp: new Date().toISOString(), + }); +}); + +app.get("/health", (req, res) => { + res.json({ status: "ok" }); +}); + +app.post("/close", (req, res) => { + res.json({ message: "Server shutting down" }); + console.log("Received shutdown request"); + process.exit(0); +}); + +app.listen(parseInt(port), () => { + console.log(`Server listening at http://localhost:${port}`); +}); \ No newline at end of file diff --git a/e2e/legacy/servers/express/package.json b/e2e/legacy/servers/express/package.json new file mode 100644 index 000000000..c73330731 --- /dev/null +++ b/e2e/legacy/servers/express/package.json @@ -0,0 +1,32 @@ +{ + "name": "express-e2e", + "private": true, + "type": "module", + "scripts": { + "dev": "tsx index.ts", + "format": "prettier -c .prettierrc --write \"**/*.{ts,js,cjs,json,md}\"", + "format:check": "prettier -c .prettierrc --check \"**/*.{ts,js,cjs,json,md}\"", + "lint": "eslint . --ext .ts --fix", + "lint:check": "eslint . --ext .ts" + }, + "dependencies": { + "@coinbase/x402": "workspace:*", + "dotenv": "^16.6.1", + "express": "^4.18.2", + "x402-express": "workspace:*" + }, + "devDependencies": { + "@eslint/js": "^9.24.0", + "@types/express": "^5.0.1", + "@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", + "tsup": "^7.2.0", + "tsx": "^4.7.0", + "typescript": "^5.3.0" + } +} \ No newline at end of file diff --git a/e2e/servers/next/run.sh b/e2e/legacy/servers/express/run.sh similarity index 100% rename from e2e/servers/next/run.sh rename to e2e/legacy/servers/express/run.sh diff --git a/e2e/legacy/servers/express/test.config.json b/e2e/legacy/servers/express/test.config.json new file mode 100644 index 000000000..d517114eb --- /dev/null +++ b/e2e/legacy/servers/express/test.config.json @@ -0,0 +1,46 @@ +{ + "name": "express", + "type": "server", + "language": "typescript", + "x402Version": 1, + "endpoints": [ + { + "path": "/protected", + "method": "GET", + "description": "Protected endpoint requiring payment", + "requiresPayment": true, + "protocolFamily": "evm" + }, + { + "path": "/protected-svm", + "method": "GET", + "description": "Protected endpoint requiring payment on SVM network", + "requiresPayment": true, + "protocolFamily": "svm" + }, + { + "path": "/health", + "method": "GET", + "description": "Health check endpoint", + "health": true + }, + { + "path": "/close", + "method": "POST", + "description": "Graceful shutdown endpoint", + "close": true + } + ], + "environment": { + "required": [ + "PORT", + "EVM_NETWORK", + "SVM_NETWORK", + "EVM_ADDRESS", + "SVM_ADDRESS" + ], + "optional": [ + "FACILITATOR_URL" + ] + } +} \ No newline at end of file diff --git a/e2e/servers/hono/tsconfig.json b/e2e/legacy/servers/express/tsconfig.json similarity index 100% rename from e2e/servers/hono/tsconfig.json rename to e2e/legacy/servers/express/tsconfig.json diff --git a/e2e/servers/fastapi/main.py b/e2e/legacy/servers/fastapi/main.py similarity index 84% rename from e2e/servers/fastapi/main.py rename to e2e/legacy/servers/fastapi/main.py index cedbdee40..8675f4935 100644 --- a/e2e/servers/fastapi/main.py +++ b/e2e/legacy/servers/fastapi/main.py @@ -21,38 +21,27 @@ load_dotenv() # Get configuration from environment -USE_CDP_FACILITATOR = os.getenv("USE_CDP_FACILITATOR", "false").lower() == "true" NETWORK = os.getenv("EVM_NETWORK", "base-sepolia") ADDRESS = os.getenv("EVM_ADDRESS") PORT = int(os.getenv("PORT", "4021")) - -# CDP facilitator configuration -CDP_API_KEY_ID = os.getenv("CDP_API_KEY_ID") -CDP_API_KEY_SECRET = os.getenv("CDP_API_KEY_SECRET") +FACILITATOR_URL = os.getenv("FACILITATOR_URL") if not ADDRESS: print("Error: Missing required environment variable ADDRESS") sys.exit(1) -# Validate CDP configuration if using CDP facilitator -if USE_CDP_FACILITATOR and (not CDP_API_KEY_ID or not CDP_API_KEY_SECRET): - print( - "Error: CDP facilitator enabled but missing CDP_API_KEY_ID or CDP_API_KEY_SECRET" - ) - sys.exit(1) - - chain_id = get_chain_id(NETWORK) address = get_default_token_address(chain_id) app = FastAPI() -# Create facilitator config if using CDP +# Create facilitator config if URL is provided facilitator_config = None -if USE_CDP_FACILITATOR: - from cdp.x402 import create_facilitator_config - - facilitator_config = create_facilitator_config(CDP_API_KEY_ID, CDP_API_KEY_SECRET) +if FACILITATOR_URL: + facilitator_config = {"url": FACILITATOR_URL} + print(f"Using remote facilitator at: {FACILITATOR_URL}") +else: + print("Using default facilitator") # Apply payment middleware to protected endpoints app.middleware("http")( @@ -159,7 +148,7 @@ def signal_handler(signum, frame): print(f"Starting FastAPI server on port {PORT}") print(f"Server address: {ADDRESS}") print(f"Network: {NETWORK}") - print(f"Using CDP facilitator: {USE_CDP_FACILITATOR}") + print(f"Using facilitator: {FACILITATOR_URL}") print("Server listening on port", PORT) uvicorn.run(app, host="0.0.0.0", port=PORT, log_level="warning") diff --git a/e2e/servers/fastapi/pyproject.toml b/e2e/legacy/servers/fastapi/pyproject.toml similarity index 88% rename from e2e/servers/fastapi/pyproject.toml rename to e2e/legacy/servers/fastapi/pyproject.toml index 3a1495fb0..b008758ab 100644 --- a/e2e/servers/fastapi/pyproject.toml +++ b/e2e/legacy/servers/fastapi/pyproject.toml @@ -25,4 +25,4 @@ allow-direct-references = true package = false [tool.uv.sources] -x402 = { path = "../../../python/x402", editable = true } \ No newline at end of file +x402 = { path = "../../../../python/x402", editable = true } \ No newline at end of file diff --git a/e2e/servers/fastapi/run.sh b/e2e/legacy/servers/fastapi/run.sh similarity index 100% rename from e2e/servers/fastapi/run.sh rename to e2e/legacy/servers/fastapi/run.sh diff --git a/e2e/servers/fastapi/test.config.json b/e2e/legacy/servers/fastapi/test.config.json similarity index 92% rename from e2e/servers/fastapi/test.config.json rename to e2e/legacy/servers/fastapi/test.config.json index 467c3f037..33bc0776e 100644 --- a/e2e/servers/fastapi/test.config.json +++ b/e2e/legacy/servers/fastapi/test.config.json @@ -2,6 +2,7 @@ "name": "fastapi", "type": "server", "language": "python", + "x402Version": 1, "description": "Python FastAPI server with x402 payment middleware", "endpoints": [ { @@ -37,10 +38,8 @@ ], "optional": [ "PORT", - "USE_CDP_FACILITATOR", "EVM_NETWORK", - "CDP_API_KEY_ID", - "CDP_API_KEY_SECRET" + "FACILITATOR_URL" ] } } \ No newline at end of file diff --git a/e2e/servers/fastapi/uv.lock b/e2e/legacy/servers/fastapi/uv.lock similarity index 99% rename from e2e/servers/fastapi/uv.lock rename to e2e/legacy/servers/fastapi/uv.lock index 1119ab203..0702c34c7 100644 --- a/e2e/servers/fastapi/uv.lock +++ b/e2e/legacy/servers/fastapi/uv.lock @@ -2119,7 +2119,7 @@ wheels = [ [[package]] name = "x402" version = "0.2.1" -source = { editable = "../../../python/x402" } +source = { editable = "../../../../python/x402" } dependencies = [ { name = "eth-account" }, { name = "eth-typing" }, @@ -2170,7 +2170,7 @@ requires-dist = [ { name = "fastapi", specifier = ">=0.104.0" }, { name = "python-dotenv", specifier = ">=1.0.0" }, { name = "uvicorn", specifier = ">=0.24.0" }, - { name = "x402", editable = "../../../python/x402" }, + { name = "x402", editable = "../../../../python/x402" }, ] [[package]] diff --git a/e2e/servers/flask/main.py b/e2e/legacy/servers/flask/main.py similarity index 79% rename from e2e/servers/flask/main.py rename to e2e/legacy/servers/flask/main.py index 8990c3dbf..7f38e860a 100644 --- a/e2e/servers/flask/main.py +++ b/e2e/legacy/servers/flask/main.py @@ -14,34 +14,24 @@ load_dotenv() # Get configuration from environment -USE_CDP_FACILITATOR = os.getenv("USE_CDP_FACILITATOR", "false").lower() == "true" NETWORK = os.getenv("EVM_NETWORK", "base-sepolia") ADDRESS = os.getenv("EVM_ADDRESS") PORT = int(os.getenv("PORT", "4021")) - -# CDP facilitator configuration -CDP_API_KEY_ID = os.getenv("CDP_API_KEY_ID") -CDP_API_KEY_SECRET = os.getenv("CDP_API_KEY_SECRET") +FACILITATOR_URL = os.getenv("FACILITATOR_URL") if not ADDRESS: print("Error: Missing required environment variable ADDRESS") sys.exit(1) -# Validate CDP configuration if using CDP facilitator -if USE_CDP_FACILITATOR and (not CDP_API_KEY_ID or not CDP_API_KEY_SECRET): - print( - "Error: CDP facilitator enabled but missing CDP_API_KEY_ID or CDP_API_KEY_SECRET" - ) - sys.exit(1) - app = Flask(__name__) -# Create facilitator config if using CDP +# Create facilitator config if URL is provided facilitator_config = None -if USE_CDP_FACILITATOR: - from cdp.x402 import create_facilitator_config - - facilitator_config = create_facilitator_config(CDP_API_KEY_ID, CDP_API_KEY_SECRET) +if FACILITATOR_URL: + facilitator_config = {"url": FACILITATOR_URL} + print(f"Using remote facilitator at: {FACILITATOR_URL}") +else: + print("Using default facilitator") # Initialize payment middleware payment_middleware = PaymentMiddleware(app) @@ -119,7 +109,7 @@ def signal_handler(signum, frame): print(f"Starting Flask server on port {PORT}") print(f"Server address: {ADDRESS}") print(f"Network: {NETWORK}") - print(f"Using CDP facilitator: {USE_CDP_FACILITATOR}") + print(f"Using facilitator: {FACILITATOR_URL}") print("Server listening on port", PORT) app.run( diff --git a/e2e/servers/flask/pyproject.toml b/e2e/legacy/servers/flask/pyproject.toml similarity index 88% rename from e2e/servers/flask/pyproject.toml rename to e2e/legacy/servers/flask/pyproject.toml index 1c67e89f0..f2abc86c0 100644 --- a/e2e/servers/flask/pyproject.toml +++ b/e2e/legacy/servers/flask/pyproject.toml @@ -24,4 +24,4 @@ allow-direct-references = true package = false [tool.uv.sources] -x402 = { path = "../../../python/x402", editable = true } \ No newline at end of file +x402 = { path = "../../../../python/x402", editable = true } \ No newline at end of file diff --git a/e2e/servers/flask/run.sh b/e2e/legacy/servers/flask/run.sh similarity index 100% rename from e2e/servers/flask/run.sh rename to e2e/legacy/servers/flask/run.sh diff --git a/e2e/servers/flask/test.config.json b/e2e/legacy/servers/flask/test.config.json similarity index 90% rename from e2e/servers/flask/test.config.json rename to e2e/legacy/servers/flask/test.config.json index 4a3655561..a73ac7bbc 100644 --- a/e2e/servers/flask/test.config.json +++ b/e2e/legacy/servers/flask/test.config.json @@ -2,6 +2,7 @@ "name": "flask", "type": "server", "language": "python", + "x402Version": 1, "description": "Python Flask server with x402 payment middleware", "endpoints": [ { @@ -30,10 +31,8 @@ ], "optional": [ "PORT", - "USE_CDP_FACILITATOR", "EVM_NETWORK", - "CDP_API_KEY_ID", - "CDP_API_KEY_SECRET" + "FACILITATOR_URL" ] } } \ No newline at end of file diff --git a/e2e/servers/flask/uv.lock b/e2e/legacy/servers/flask/uv.lock similarity index 99% rename from e2e/servers/flask/uv.lock rename to e2e/legacy/servers/flask/uv.lock index 91000328d..a13cd6857 100644 --- a/e2e/servers/flask/uv.lock +++ b/e2e/legacy/servers/flask/uv.lock @@ -2119,7 +2119,7 @@ wheels = [ [[package]] name = "x402" version = "0.2.1" -source = { editable = "../../../python/x402" } +source = { editable = "../../../../python/x402" } dependencies = [ { name = "eth-account" }, { name = "eth-typing" }, @@ -2168,7 +2168,7 @@ requires-dist = [ { name = "cdp-sdk", specifier = ">=1.15.0" }, { name = "flask", specifier = ">=3.0.0" }, { name = "python-dotenv", specifier = ">=1.0.0" }, - { name = "x402", editable = "../../../python/x402" }, + { name = "x402", editable = "../../../../python/x402" }, ] [[package]] diff --git a/e2e/legacy/servers/gin/go.mod b/e2e/legacy/servers/gin/go.mod new file mode 100644 index 000000000..5c21953de --- /dev/null +++ b/e2e/legacy/servers/gin/go.mod @@ -0,0 +1,42 @@ +module github.com/coinbase/x402/e2e/servers/gin + +go 1.23.3 + +require ( + github.com/coinbase/x402/go v0.0.0-00010101000000-000000000000 + github.com/gin-gonic/gin v1.10.0 + github.com/joho/godotenv v1.5.1 +) + +require ( + github.com/bytedance/sonic v1.13.2 // indirect + github.com/bytedance/sonic/loader v0.2.4 // indirect + github.com/cloudwego/base64x v0.1.5 // indirect + github.com/gabriel-vasile/mimetype v1.4.8 // indirect + github.com/gin-contrib/sse v1.0.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.26.0 // indirect + github.com/goccy/go-json v0.10.5 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.10 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + golang.org/x/arch v0.15.0 // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/net v0.38.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/text v0.23.0 // indirect + google.golang.org/protobuf v1.36.6 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +replace github.com/coinbase/x402/go => ../../../../go/legacy diff --git a/e2e/legacy/servers/gin/go.sum b/e2e/legacy/servers/gin/go.sum new file mode 100644 index 000000000..589bce8e7 --- /dev/null +++ b/e2e/legacy/servers/gin/go.sum @@ -0,0 +1,101 @@ +github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ= +github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= +github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= +github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= +github.com/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E= +github.com/gin-contrib/sse v1.0.0/go.mod h1:zNuFdwarAygJBht0NTKiSi3jRf6RbqeILZ9Sp6Slhe0= +github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= +github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k= +github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= +github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= +github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= +github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +golang.org/x/arch v0.15.0 h1:QtOrQd0bTUnhNVNndMpLHNWrDmYzZ2KDqSrEymqInZw= +golang.org/x/arch v0.15.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= diff --git a/e2e/legacy/servers/gin/main.go b/e2e/legacy/servers/gin/main.go new file mode 100644 index 000000000..720cc2de2 --- /dev/null +++ b/e2e/legacy/servers/gin/main.go @@ -0,0 +1,142 @@ +package main + +import ( + "fmt" + "math/big" + "net/http" + "os" + "os/signal" + "syscall" + "time" + + x402gin "github.com/coinbase/x402/go/pkg/gin" + "github.com/coinbase/x402/go/pkg/types" + "github.com/gin-gonic/gin" + "github.com/joho/godotenv" +) + +var shutdownRequested bool + +func main() { + // Load .env file if it exists + if err := godotenv.Load(); err != nil { + fmt.Println("Warning: .env file not found. Using environment variables.") + } + + // Get configuration from environment + network := os.Getenv("EVM_NETWORK") + if network == "" { + network = "base-sepolia" + } + address := os.Getenv("EVM_ADDRESS") + port := os.Getenv("PORT") + if port == "" { + port = "4021" + } + facilitatorURL := os.Getenv("FACILITATOR_URL") + + if address == "" { + fmt.Println("Error: Missing required environment variable ADDRESS") + os.Exit(1) + } + + // Create facilitator config if URL is provided + var facilitatorConfig *types.FacilitatorConfig + if facilitatorURL != "" { + facilitatorConfig = &types.FacilitatorConfig{ + URL: facilitatorURL, + } + fmt.Printf("Using remote facilitator at: %s\n", facilitatorURL) + } else { + fmt.Println("Using default facilitator") + } + + // Set Gin to release mode to reduce logs + gin.SetMode(gin.ReleaseMode) + r := gin.New() + r.Use(gin.Recovery()) + + // Protected endpoint that requires payment + r.GET("/protected", + x402gin.PaymentMiddleware( + big.NewFloat(0.001), // $0.001 USD + address, + x402gin.WithFacilitatorConfig(facilitatorConfig), + x402gin.WithDescription("Protected endpoint requiring payment"), + x402gin.WithResource("http://localhost:"+port+"/protected"), + x402gin.WithTestnet(network == "base-sepolia"), + ), + func(c *gin.Context) { + if shutdownRequested { + c.JSON(http.StatusServiceUnavailable, gin.H{ + "error": "Server shutting down", + }) + return + } + + c.JSON(http.StatusOK, gin.H{ + "message": "Access granted to protected resource", + "timestamp": "2024-01-01T00:00:00Z", + "data": gin.H{ + "resource": "premium_content", + "access_level": "paid", + }, + }) + }, + ) + + // Health check endpoint + r.GET("/health", func(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{ + "status": "healthy", + "timestamp": "2024-01-01T00:00:00Z", + "server": "gin", + }) + }) + + // Graceful shutdown endpoint + r.POST("/close", func(c *gin.Context) { + shutdownRequested = true + + c.JSON(http.StatusOK, gin.H{ + "message": "Server shutting down gracefully", + "timestamp": "2024-01-01T00:00:00Z", + }) + + // Schedule server shutdown after response + go func() { + time.Sleep(100 * time.Millisecond) + os.Exit(0) + }() + }) + + // Set up graceful shutdown + quit := make(chan os.Signal, 1) + signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) + + go func() { + <-quit + fmt.Println("Received shutdown signal, exiting...") + os.Exit(0) + }() + + fmt.Printf("Starting Gin server on port %s\n", port) + fmt.Printf("Server address: %s\n", address) + fmt.Printf("Network: %s\n", network) + if facilitatorURL != "" { + fmt.Printf("Using facilitator: %s\n", facilitatorURL) + } else { + fmt.Printf("Using default facilitator\n") + } + fmt.Printf("Server listening on port %s\n", port) + + server := &http.Server{ + Addr: ":" + port, + Handler: r, + } + + if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { + fmt.Printf("Error starting server: %v\n", err) + os.Exit(1) + } +} diff --git a/e2e/legacy/servers/gin/run.sh b/e2e/legacy/servers/gin/run.sh new file mode 100644 index 000000000..00637611b --- /dev/null +++ b/e2e/legacy/servers/gin/run.sh @@ -0,0 +1,2 @@ +#!/bin/bash +go run main.go \ No newline at end of file diff --git a/e2e/legacy/servers/gin/test.config.json b/e2e/legacy/servers/gin/test.config.json new file mode 100644 index 000000000..caff6387b --- /dev/null +++ b/e2e/legacy/servers/gin/test.config.json @@ -0,0 +1,38 @@ +{ + "name": "gin", + "type": "server", + "language": "go", + "x402Version": 1, + "description": "Go Gin server with x402 payment middleware", + "endpoints": [ + { + "path": "/protected", + "method": "GET", + "description": "Protected endpoint requiring payment", + "requiresPayment": true, + "protocolFamily": "evm" + }, + { + "path": "/health", + "method": "GET", + "description": "Health check endpoint", + "health": true + }, + { + "path": "/close", + "method": "POST", + "description": "Graceful shutdown endpoint", + "close": true + } + ], + "environment": { + "required": [ + "EVM_ADDRESS" + ], + "optional": [ + "PORT", + "EVM_NETWORK", + "FACILITATOR_URL" + ] + } +} \ No newline at end of file diff --git a/e2e/servers/hono/.env-local b/e2e/legacy/servers/hono/.env-local similarity index 100% rename from e2e/servers/hono/.env-local rename to e2e/legacy/servers/hono/.env-local diff --git a/examples/typescript/agent/.prettierignore b/e2e/legacy/servers/hono/.prettierignore similarity index 100% rename from examples/typescript/agent/.prettierignore rename to e2e/legacy/servers/hono/.prettierignore diff --git a/examples/typescript/agent/.prettierrc b/e2e/legacy/servers/hono/.prettierrc similarity index 100% rename from examples/typescript/agent/.prettierrc rename to e2e/legacy/servers/hono/.prettierrc diff --git a/e2e/servers/hono/README.md b/e2e/legacy/servers/hono/README.md similarity index 100% rename from e2e/servers/hono/README.md rename to e2e/legacy/servers/hono/README.md diff --git a/examples/typescript/facilitator/eslint.config.js b/e2e/legacy/servers/hono/eslint.config.js similarity index 100% rename from examples/typescript/facilitator/eslint.config.js rename to e2e/legacy/servers/hono/eslint.config.js diff --git a/e2e/servers/hono/index.ts b/e2e/legacy/servers/hono/index.ts similarity index 71% rename from e2e/servers/hono/index.ts rename to e2e/legacy/servers/hono/index.ts index c4a87ca22..12eae3c9b 100644 --- a/e2e/servers/hono/index.ts +++ b/e2e/legacy/servers/hono/index.ts @@ -1,21 +1,31 @@ import { config } from "dotenv"; import { Hono } from "hono"; import { serve } from "@hono/node-server"; -import { paymentMiddleware, Network, Resource } from "x402-hono"; -import { facilitator } from "@coinbase/x402"; +import { paymentMiddleware, Network, Resource, FacilitatorConfig } from "x402-hono"; config(); -const useCdpFacilitator = process.env.USE_CDP_FACILITATOR === 'true'; const payTo = process.env.EVM_ADDRESS as `0x${string}`; const network = process.env.EVM_NETWORK as Network; const port = parseInt(process.env.PORT || '4021'); +const facilitatorUrl = process.env.FACILITATOR_URL; if (!payTo || !network) { console.error("Missing required environment variables"); process.exit(1); } +// Create facilitator config if URL is provided +const facilitatorConfig: FacilitatorConfig | undefined = facilitatorUrl + ? { url: facilitatorUrl as Resource } + : undefined; + +if (facilitatorUrl) { + console.log(`Using remote facilitator at: ${facilitatorUrl}`); +} else { + console.log(`Using default facilitator`); +} + const app = new Hono(); // Apply payment middleware to protected endpoint @@ -28,9 +38,7 @@ app.use( network, }, }, - useCdpFacilitator - ? facilitator - : undefined, + facilitatorConfig, ), ); diff --git a/e2e/servers/hono/package.json b/e2e/legacy/servers/hono/package.json similarity index 100% rename from e2e/servers/hono/package.json rename to e2e/legacy/servers/hono/package.json diff --git a/e2e/legacy/servers/hono/run.sh b/e2e/legacy/servers/hono/run.sh new file mode 100755 index 000000000..aa2c67d61 --- /dev/null +++ b/e2e/legacy/servers/hono/run.sh @@ -0,0 +1,2 @@ +#!/bin/bash +pnpm dev \ No newline at end of file diff --git a/e2e/servers/hono/test.config.json b/e2e/legacy/servers/hono/test.config.json similarity index 89% rename from e2e/servers/hono/test.config.json rename to e2e/legacy/servers/hono/test.config.json index 857ef5e87..54c699e0c 100644 --- a/e2e/servers/hono/test.config.json +++ b/e2e/legacy/servers/hono/test.config.json @@ -2,6 +2,7 @@ "name": "hono", "type": "server", "language": "typescript", + "x402Version": 1, "endpoints": [ { "path": "/protected", @@ -26,13 +27,11 @@ "environment": { "required": [ "PORT", - "USE_CDP_FACILITATOR", "EVM_NETWORK", "EVM_ADDRESS" ], "optional": [ - "CDP_API_KEY_ID", - "CDP_API_KEY_SECRET" + "FACILITATOR_URL" ] } } \ No newline at end of file diff --git a/examples/typescript/clients/axios/tsconfig.json b/e2e/legacy/servers/hono/tsconfig.json similarity index 100% rename from examples/typescript/clients/axios/tsconfig.json rename to e2e/legacy/servers/hono/tsconfig.json diff --git a/e2e/servers/next/.env-local b/e2e/legacy/servers/next/.env-local similarity index 100% rename from e2e/servers/next/.env-local rename to e2e/legacy/servers/next/.env-local diff --git a/e2e/servers/next/.gitignore b/e2e/legacy/servers/next/.gitignore similarity index 100% rename from e2e/servers/next/.gitignore rename to e2e/legacy/servers/next/.gitignore diff --git a/examples/typescript/clients/axios/.prettierignore b/e2e/legacy/servers/next/.prettierignore similarity index 100% rename from examples/typescript/clients/axios/.prettierignore rename to e2e/legacy/servers/next/.prettierignore diff --git a/examples/typescript/clients/axios/.prettierrc b/e2e/legacy/servers/next/.prettierrc similarity index 100% rename from examples/typescript/clients/axios/.prettierrc rename to e2e/legacy/servers/next/.prettierrc diff --git a/e2e/servers/next/README.md b/e2e/legacy/servers/next/README.md similarity index 100% rename from e2e/servers/next/README.md rename to e2e/legacy/servers/next/README.md diff --git a/e2e/servers/next/app/api/close/route.ts b/e2e/legacy/servers/next/app/api/close/route.ts similarity index 100% rename from e2e/servers/next/app/api/close/route.ts rename to e2e/legacy/servers/next/app/api/close/route.ts diff --git a/e2e/servers/next/app/api/health/route.ts b/e2e/legacy/servers/next/app/api/health/route.ts similarity index 100% rename from e2e/servers/next/app/api/health/route.ts rename to e2e/legacy/servers/next/app/api/health/route.ts diff --git a/e2e/servers/next/app/api/protected/route.ts b/e2e/legacy/servers/next/app/api/protected/route.ts similarity index 100% rename from e2e/servers/next/app/api/protected/route.ts rename to e2e/legacy/servers/next/app/api/protected/route.ts diff --git a/e2e/servers/next/app/assets/x402_wordmark_dark.png b/e2e/legacy/servers/next/app/assets/x402_wordmark_dark.png similarity index 100% rename from e2e/servers/next/app/assets/x402_wordmark_dark.png rename to e2e/legacy/servers/next/app/assets/x402_wordmark_dark.png diff --git a/e2e/servers/next/app/assets/x402_wordmark_dark.svg b/e2e/legacy/servers/next/app/assets/x402_wordmark_dark.svg similarity index 100% rename from e2e/servers/next/app/assets/x402_wordmark_dark.svg rename to e2e/legacy/servers/next/app/assets/x402_wordmark_dark.svg diff --git a/e2e/servers/next/app/assets/x402_wordmark_light.svg b/e2e/legacy/servers/next/app/assets/x402_wordmark_light.svg similarity index 100% rename from e2e/servers/next/app/assets/x402_wordmark_light.svg rename to e2e/legacy/servers/next/app/assets/x402_wordmark_light.svg diff --git a/e2e/servers/next/app/favicon.ico b/e2e/legacy/servers/next/app/favicon.ico similarity index 100% rename from e2e/servers/next/app/favicon.ico rename to e2e/legacy/servers/next/app/favicon.ico diff --git a/e2e/servers/next/app/globals.css b/e2e/legacy/servers/next/app/globals.css similarity index 100% rename from e2e/servers/next/app/globals.css rename to e2e/legacy/servers/next/app/globals.css diff --git a/e2e/servers/next/app/layout.tsx b/e2e/legacy/servers/next/app/layout.tsx similarity index 100% rename from e2e/servers/next/app/layout.tsx rename to e2e/legacy/servers/next/app/layout.tsx diff --git a/e2e/servers/next/app/page.tsx b/e2e/legacy/servers/next/app/page.tsx similarity index 100% rename from e2e/servers/next/app/page.tsx rename to e2e/legacy/servers/next/app/page.tsx diff --git a/e2e/servers/next/app/protected/page.tsx b/e2e/legacy/servers/next/app/protected/page.tsx similarity index 100% rename from e2e/servers/next/app/protected/page.tsx rename to e2e/legacy/servers/next/app/protected/page.tsx diff --git a/e2e/servers/next/eslint.config.js b/e2e/legacy/servers/next/eslint.config.js similarity index 100% rename from e2e/servers/next/eslint.config.js rename to e2e/legacy/servers/next/eslint.config.js diff --git a/e2e/servers/next/middleware.ts b/e2e/legacy/servers/next/middleware.ts similarity index 59% rename from e2e/servers/next/middleware.ts rename to e2e/legacy/servers/next/middleware.ts index b019da584..625c3adf6 100644 --- a/e2e/servers/next/middleware.ts +++ b/e2e/legacy/servers/next/middleware.ts @@ -1,16 +1,21 @@ import { Address } from "viem"; -import { paymentMiddleware, Network, Resource } from "x402-next"; -import { facilitator } from "@coinbase/x402"; +import { paymentMiddleware, Network, Resource, FacilitatorConfig } from "x402-next"; -const useCdpFacilitator = process.env.USE_CDP_FACILITATOR === 'true'; const payTo = process.env.EVM_ADDRESS as Address; const network = process.env.EVM_NETWORK as Network; +const facilitatorUrl = process.env.FACILITATOR_URL; -// Configure facilitator -const facilitatorConfig = useCdpFacilitator - ? facilitator +// Create facilitator config if URL is provided +const facilitatorConfig: FacilitatorConfig | undefined = facilitatorUrl + ? { url: facilitatorUrl as Resource } : undefined; +if (facilitatorUrl) { + console.log(`Using remote facilitator at: ${facilitatorUrl}`); +} else { + console.log(`Using default facilitator`); +} + export const middleware = paymentMiddleware( payTo, { diff --git a/e2e/servers/next/next.config.ts b/e2e/legacy/servers/next/next.config.ts similarity index 71% rename from e2e/servers/next/next.config.ts rename to e2e/legacy/servers/next/next.config.ts index 2a7522e59..752b68b77 100644 --- a/e2e/servers/next/next.config.ts +++ b/e2e/legacy/servers/next/next.config.ts @@ -4,13 +4,10 @@ const nextConfig: NextConfig = { experimental: { nodeMiddleware: true, // TEMPORARY: Only needed until Edge runtime support is added }, - serverExternalPackages: ["@coinbase/cdp-sdk"], env: { - ADDRESS: process.env.ADDRESS, - USE_CDP_FACILITATOR: process.env.USE_CDP_FACILITATOR, - CDP_API_KEY_ID: process.env.CDP_API_KEY_ID, - CDP_API_KEY_SECRET: process.env.CDP_API_KEY_SECRET, - NETWORK: process.env.NETWORK, + EVM_ADDRESS: process.env.EVM_ADDRESS, + EVM_NETWORK: process.env.EVM_NETWORK, + FACILITATOR_URL: process.env.FACILITATOR_URL, PORT: process.env.PORT, }, webpack(config) { diff --git a/e2e/servers/next/package-lock.json b/e2e/legacy/servers/next/package-lock.json similarity index 100% rename from e2e/servers/next/package-lock.json rename to e2e/legacy/servers/next/package-lock.json diff --git a/e2e/servers/next/package.json b/e2e/legacy/servers/next/package.json similarity index 98% rename from e2e/servers/next/package.json rename to e2e/legacy/servers/next/package.json index 77370e756..50aac0c36 100644 --- a/e2e/servers/next/package.json +++ b/e2e/legacy/servers/next/package.json @@ -15,7 +15,7 @@ "dependencies": { "@coinbase/x402": "workspace:*", "@heroicons/react": "^2.2.0", - "next": "canary", + "next": "^15.1.7", "react": "^19.0.0", "react-dom": "^19.0.0", "viem": "^2.21.26", diff --git a/e2e/servers/next/postcss.config.mjs b/e2e/legacy/servers/next/postcss.config.mjs similarity index 100% rename from e2e/servers/next/postcss.config.mjs rename to e2e/legacy/servers/next/postcss.config.mjs diff --git a/e2e/servers/next/public/apple-touch-icon.png b/e2e/legacy/servers/next/public/apple-touch-icon.png similarity index 100% rename from e2e/servers/next/public/apple-touch-icon.png rename to e2e/legacy/servers/next/public/apple-touch-icon.png diff --git a/e2e/servers/next/public/favicon-96x96.png b/e2e/legacy/servers/next/public/favicon-96x96.png similarity index 100% rename from e2e/servers/next/public/favicon-96x96.png rename to e2e/legacy/servers/next/public/favicon-96x96.png diff --git a/e2e/servers/next/public/favicon.svg b/e2e/legacy/servers/next/public/favicon.svg similarity index 100% rename from e2e/servers/next/public/favicon.svg rename to e2e/legacy/servers/next/public/favicon.svg diff --git a/e2e/servers/next/public/site.webmanifest b/e2e/legacy/servers/next/public/site.webmanifest similarity index 100% rename from e2e/servers/next/public/site.webmanifest rename to e2e/legacy/servers/next/public/site.webmanifest diff --git a/e2e/servers/next/public/web-app-manifest-192x192.png b/e2e/legacy/servers/next/public/web-app-manifest-192x192.png similarity index 100% rename from e2e/servers/next/public/web-app-manifest-192x192.png rename to e2e/legacy/servers/next/public/web-app-manifest-192x192.png diff --git a/e2e/servers/next/public/web-app-manifest-512x512.png b/e2e/legacy/servers/next/public/web-app-manifest-512x512.png similarity index 100% rename from e2e/servers/next/public/web-app-manifest-512x512.png rename to e2e/legacy/servers/next/public/web-app-manifest-512x512.png diff --git a/e2e/servers/next/public/x402-icon-blue.png b/e2e/legacy/servers/next/public/x402-icon-blue.png similarity index 100% rename from e2e/servers/next/public/x402-icon-blue.png rename to e2e/legacy/servers/next/public/x402-icon-blue.png diff --git a/e2e/legacy/servers/next/run.sh b/e2e/legacy/servers/next/run.sh new file mode 100755 index 000000000..aa2c67d61 --- /dev/null +++ b/e2e/legacy/servers/next/run.sh @@ -0,0 +1,2 @@ +#!/bin/bash +pnpm dev \ No newline at end of file diff --git a/e2e/servers/next/tailwind.config.ts b/e2e/legacy/servers/next/tailwind.config.ts similarity index 100% rename from e2e/servers/next/tailwind.config.ts rename to e2e/legacy/servers/next/tailwind.config.ts diff --git a/e2e/servers/next/test.config.json b/e2e/legacy/servers/next/test.config.json similarity index 89% rename from e2e/servers/next/test.config.json rename to e2e/legacy/servers/next/test.config.json index 3bb162348..57e618366 100644 --- a/e2e/servers/next/test.config.json +++ b/e2e/legacy/servers/next/test.config.json @@ -2,6 +2,7 @@ "name": "next", "type": "server", "language": "typescript", + "x402Version": 1, "endpoints": [ { "path": "/api/protected", @@ -26,13 +27,11 @@ "environment": { "required": [ "PORT", - "USE_CDP_FACILITATOR", "EVM_NETWORK", "EVM_ADDRESS" ], "optional": [ - "CDP_API_KEY_ID", - "CDP_API_KEY_SECRET" + "FACILITATOR_URL" ] } } \ No newline at end of file diff --git a/examples/typescript/fullstack/next/tsconfig.json b/e2e/legacy/servers/next/tsconfig.json similarity index 58% rename from examples/typescript/fullstack/next/tsconfig.json rename to e2e/legacy/servers/next/tsconfig.json index 84ffc5cc8..7060fc92a 100644 --- a/examples/typescript/fullstack/next/tsconfig.json +++ b/e2e/legacy/servers/next/tsconfig.json @@ -1,7 +1,11 @@ { "compilerOptions": { "target": "ES2022", - "lib": ["dom", "dom.iterable", "esnext"], + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], "allowJs": true, "skipLibCheck": true, "strict": false, @@ -19,9 +23,20 @@ } ], "paths": { - "@/*": ["./*"] + "@/*": [ + "./*" + ] } }, - "include": ["types/video.d.ts", "next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], - "exclude": ["node_modules"] + "include": [ + "types/video.d.ts", + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + ".next/dev/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] } diff --git a/e2e/servers/next/types/svg.d.ts b/e2e/legacy/servers/next/types/svg.d.ts similarity index 100% rename from e2e/servers/next/types/svg.d.ts rename to e2e/legacy/servers/next/types/svg.d.ts diff --git a/e2e/package.json b/e2e/package.json index fbdf38b92..91eb3f4f2 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -7,18 +7,15 @@ "build": "tsc", "test": "tsx test.ts", "test:watch": "tsc --watch", - "clean": "rm -rf dist" + "clean": "rm -rf dist", + "clean:ports": "lsof -ti:4022,4023,4024,4025,4026,4027,4028,4029,4030 | xargs kill -9 2>/dev/null || echo 'Ports cleared'" }, "dependencies": { - "@coinbase/x402": "workspace:*", "axios": "^1.6.0", "dotenv": "^17.0.1", "express": "^4.18.0", "tsx": "^4.20.3", - "viem": "^2.0.0", - "x402": "workspace:*", - "x402-axios": "workspace:*", - "x402-express": "workspace:*" + "viem": "^2.0.0" }, "devDependencies": { "@types/express": "^4.17.0", diff --git a/e2e/pnpm-lock.yaml b/e2e/pnpm-lock.yaml index 2c1b31119..1c65c4b05 100644 --- a/e2e/pnpm-lock.yaml +++ b/e2e/pnpm-lock.yaml @@ -8,9 +8,6 @@ importers: .: dependencies: - '@coinbase/x402': - specifier: workspace:* - version: link:../typescript/packages/coinbase-x402 axios: specifier: ^1.6.0 version: 1.10.0 @@ -21,36 +18,494 @@ importers: specifier: ^4.18.0 version: 4.21.2 tsx: - specifier: ^4.20.3 + specifier: ^4.20.3 + version: 4.20.3 + viem: + specifier: ^2.0.0 + version: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + devDependencies: + '@types/express': + specifier: ^4.17.0 + version: 4.17.23 + '@types/node': + specifier: ^20.0.0 + version: 20.19.4 + typescript: + specifier: ^5.0.0 + version: 5.8.3 + + ../typescript/packages/core: + dependencies: + zod: + specifier: ^3.24.2 + version: 3.25.71 + devDependencies: + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 + '@types/node': + specifier: ^22.13.4 + version: 22.16.0 + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.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.3)(typescript@5.8.3)(yaml@2.8.1) + tsx: + specifier: ^4.19.2 + version: 4.20.3 + typescript: + specifier: ^5.7.3 + version: 5.8.3 + vite: + specifier: ^6.2.6 + version: 6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.8.3)(vite@6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1)) + vitest: + specifier: ^3.0.5 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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.1) + + ../typescript/packages/extensions: + dependencies: + '@x402/core': + specifier: workspace:* + version: link:../core + ajv: + specifier: ^8.17.1 + version: 8.17.1 + zod: + specifier: ^3.24.2 + version: 3.25.71 + devDependencies: + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 + '@types/node': + specifier: ^22.13.4 + version: 22.16.0 + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.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.3)(typescript@5.8.3)(yaml@2.8.1) + tsx: + specifier: ^4.19.2 + version: 4.20.3 + typescript: + specifier: ^5.7.3 + version: 5.8.3 + vite: + specifier: ^6.2.6 + version: 6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.8.3)(vite@6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1)) + vitest: + specifier: ^3.0.5 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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.1) + + ../typescript/packages/http/axios: + dependencies: + '@x402/core': + specifier: workspace:* + version: link:../../core + axios: + specifier: ^1.7.9 + version: 1.12.2 + zod: + specifier: ^3.24.2 + version: 3.25.71 + devDependencies: + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 + '@types/node': + specifier: ^22.13.4 + version: 22.16.0 + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.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.3)(typescript@5.8.3)(yaml@2.8.1) + tsx: + specifier: ^4.19.2 + version: 4.20.3 + typescript: + specifier: ^5.7.3 + version: 5.8.3 + vite: + specifier: ^6.2.6 + version: 6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.8.3)(vite@6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1)) + vitest: + specifier: ^3.0.5 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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.1) + + ../typescript/packages/http/express: + dependencies: + '@coinbase/cdp-sdk': + specifier: ^1.22.0 + version: 1.38.4(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/kit': + specifier: ^2.1.1 + 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)) + '@x402/core': + specifier: workspace:^ + version: link:../../core + express: + specifier: ^4.18.2 + version: 4.21.2 + viem: + specifier: ^2.21.26 + version: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + zod: + specifier: ^3.24.2 + version: 3.25.71 + devDependencies: + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 + '@types/express': + specifier: ^5.0.1 + version: 5.0.3 + '@types/node': + specifier: ^22.13.4 + version: 22.16.0 + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.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.3)(typescript@5.8.3)(yaml@2.8.1) + tsx: + specifier: ^4.19.2 + version: 4.20.3 + typescript: + specifier: ^5.7.3 + version: 5.8.3 + vite: + specifier: ^6.2.6 + version: 6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.8.3)(vite@6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1)) + vitest: + specifier: ^3.0.5 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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.1) + + ../typescript/packages/http/fetch: + dependencies: + '@x402/core': + specifier: workspace:^ + version: link:../../core + viem: + specifier: ^2.21.26 + version: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + zod: + specifier: ^3.24.2 + version: 3.25.71 + devDependencies: + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 + '@types/node': + specifier: ^22.13.4 + version: 22.16.0 + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.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.3)(typescript@5.8.3)(yaml@2.8.1) + tsx: + specifier: ^4.19.2 + version: 4.20.3 + typescript: + specifier: ^5.7.3 + version: 5.8.3 + vite: + specifier: ^6.2.6 + version: 6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.8.3)(vite@6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1)) + vitest: + specifier: ^3.0.5 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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.1) + + ../typescript/packages/http/hono: + dependencies: + '@x402/core': + specifier: workspace:* + version: link:../../core + hono: + specifier: ^4.7.1 + version: 4.10.2 + zod: + specifier: ^3.24.2 + version: 3.25.71 + devDependencies: + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 + '@types/node': + specifier: ^22.13.4 + version: 22.16.0 + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.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.3)(typescript@5.8.3)(yaml@2.8.1) + tsx: + specifier: ^4.19.2 + version: 4.20.3 + typescript: + specifier: ^5.7.3 + version: 5.8.3 + vite: + specifier: ^6.2.6 + version: 6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.8.3)(vite@6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1)) + vitest: + specifier: ^3.0.5 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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.1) + + ../typescript/packages/http/next: + dependencies: + '@x402/core': + specifier: workspace:* + version: link:../../core + next: + specifier: ^15.0.0 + version: 15.5.6(@babel/core@7.28.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + zod: + specifier: ^3.24.2 + version: 3.25.71 + devDependencies: + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 + '@types/node': + specifier: ^22.13.4 + version: 22.16.0 + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.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.3)(typescript@5.8.3)(yaml@2.8.1) + tsx: + specifier: ^4.19.2 version: 4.20.3 - viem: - specifier: ^2.0.0 - version: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) - x402: - specifier: workspace:* - version: link:../typescript/packages/x402 - x402-axios: - specifier: workspace:* - version: link:../typescript/packages/x402-axios - x402-express: + typescript: + specifier: ^5.7.3 + version: 5.8.3 + vite: + specifier: ^6.2.6 + version: 6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.8.3)(vite@6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1)) + vitest: + specifier: ^3.0.5 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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.1) + + ../typescript/packages/http/paywall: + dependencies: + '@x402/core': specifier: workspace:* - version: link:../typescript/packages/x402-express + version: link:../../core + zod: + specifier: ^3.24.2 + version: 3.25.71 devDependencies: - '@types/express': - specifier: ^4.17.0 - version: 4.17.23 + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 '@types/node': - specifier: ^20.0.0 - version: 20.19.4 + specifier: ^22.13.4 + version: 22.16.0 + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.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.3)(typescript@5.8.3)(yaml@2.8.1) + tsx: + specifier: ^4.19.2 + version: 4.20.3 typescript: - specifier: ^5.0.0 + specifier: ^5.7.3 version: 5.8.3 + vite: + specifier: ^6.2.6 + version: 6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.8.3)(vite@6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1)) + vitest: + specifier: ^3.0.5 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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.1) - ../typescript/packages/coinbase-x402: + ../typescript/packages/legacy/coinbase-x402: dependencies: '@coinbase/cdp-sdk': specifier: ^1.29.0 - version: 1.38.0(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10) + version: 1.38.4(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) viem: specifier: ^2.21.26 version: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) @@ -63,34 +518,34 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.30.1 + version: 9.38.0 '@types/node': specifier: ^22.13.4 version: 22.16.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) eslint: specifier: ^9.24.0 - version: 9.30.1(jiti@1.21.7) + version: 9.38.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.30.1(jiti@1.21.7)) + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.1(eslint@9.30.1(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint@9.38.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.3)(typescript@5.8.3)(yaml@2.8.0) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.1) tsx: specifier: ^4.19.2 version: 4.20.3 @@ -99,15 +554,15 @@ importers: version: 5.8.3 vite: specifier: ^6.2.6 - version: 6.3.5(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) + version: 6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.8.3)(vite@6.3.5(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0)) + version: 5.1.4(typescript@5.8.3)(vite@6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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.1) - ../typescript/packages/x402: + ../typescript/packages/legacy/x402: dependencies: '@scure/base': specifier: ^1.2.6 @@ -120,7 +575,7 @@ importers: 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.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)) + 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@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)) '@solana/kit': specifier: ^2.1.1 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)) @@ -132,41 +587,41 @@ importers: version: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) wagmi: specifier: ^2.15.6 - version: 2.15.6(@tanstack/query-core@5.81.5)(@tanstack/react-query@5.81.5(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.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71) + version: 2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71) zod: specifier: ^3.24.2 version: 3.25.71 devDependencies: '@coinbase/onchainkit': specifier: ^0.38.14 - version: 0.38.15(@tanstack/query-core@5.81.5)(@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.71) + version: 0.38.19(@farcaster/miniapp-sdk@0.2.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@3.25.71) '@craftamap/esbuild-plugin-html': specifier: ^0.9.0 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.30.1 + version: 9.38.0 '@types/node': specifier: ^22.13.4 version: 22.16.0 '@types/react': specifier: ^19 - version: 19.1.8 + version: 19.2.2 '@types/react-dom': specifier: ^19 - version: 19.1.6(@types/react@19.1.8) + version: 19.2.2(@types/react@19.2.2) '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) '@wagmi/connectors': specifier: ^5.8.1 - version: 5.8.5(@types/react@19.1.8)(@wagmi/core@2.17.3(@tanstack/query-core@5.81.5)(@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.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)))(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71) + version: 5.11.2(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)))(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71))(zod@3.25.71) '@wagmi/core': specifier: ^2.17.1 - version: 2.17.3(@tanstack/query-core@5.81.5)(@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.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)) + version: 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)) buffer: specifier: ^6.0.3 version: 6.0.3 @@ -175,28 +630,28 @@ importers: version: 0.25.5 eslint: specifier: ^9.24.0 - version: 9.30.1(jiti@1.21.7) + version: 9.38.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.30.1(jiti@1.21.7)) + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.1(eslint@9.30.1(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint@9.38.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.0 + version: 19.2.0 react-dom: specifier: ^19.0.0 - version: 19.1.0(react@19.1.0) + version: 19.2.0(react@19.2.0) tsup: specifier: ^8.4.0 - version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.1) tsx: specifier: ^4.19.2 version: 4.20.3 @@ -205,15 +660,15 @@ importers: version: 5.8.3 vite: specifier: ^6.2.6 - version: 6.3.5(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) + version: 6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.8.3)(vite@6.3.5(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0)) + version: 5.1.4(typescript@5.8.3)(vite@6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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.1) - ../typescript/packages/x402-axios: + ../typescript/packages/legacy/x402-axios: dependencies: axios: specifier: ^1.7.9 @@ -230,34 +685,34 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.30.1 + version: 9.38.0 '@types/node': specifier: ^22.13.4 version: 22.16.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) eslint: specifier: ^9.24.0 - version: 9.30.1(jiti@1.21.7) + version: 9.38.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.30.1(jiti@1.21.7)) + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.1(eslint@9.30.1(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint@9.38.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.3)(typescript@5.8.3)(yaml@2.8.0) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.1) tsx: specifier: ^4.19.2 version: 4.20.3 @@ -266,19 +721,19 @@ importers: version: 5.8.3 vite: specifier: ^6.2.6 - version: 6.3.5(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) + version: 6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.8.3)(vite@6.3.5(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0)) + version: 5.1.4(typescript@5.8.3)(vite@6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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.1) - ../typescript/packages/x402-express: + ../typescript/packages/legacy/x402-express: dependencies: '@coinbase/cdp-sdk': specifier: ^1.22.0 - version: 1.38.0(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10) + version: 1.38.4(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@solana/kit': specifier: ^2.1.1 version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) @@ -297,7 +752,7 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.30.1 + version: 9.38.0 '@types/express': specifier: ^5.0.1 version: 5.0.3 @@ -306,28 +761,28 @@ importers: version: 22.16.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) eslint: specifier: ^9.24.0 - version: 9.30.1(jiti@1.21.7) + version: 9.38.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.30.1(jiti@1.21.7)) + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.1(eslint@9.30.1(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint@9.38.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.3)(typescript@5.8.3)(yaml@2.8.0) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.1) tsx: specifier: ^4.19.2 version: 4.20.3 @@ -336,15 +791,15 @@ importers: version: 5.8.3 vite: specifier: ^6.2.6 - version: 6.3.5(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) + version: 6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.8.3)(vite@6.3.5(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0)) + version: 5.1.4(typescript@5.8.3)(vite@6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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.1) - ../typescript/packages/x402-fetch: + ../typescript/packages/legacy/x402-fetch: dependencies: viem: specifier: ^2.21.26 @@ -358,34 +813,34 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.30.1 + version: 9.38.0 '@types/node': specifier: ^22.13.4 version: 22.16.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) eslint: specifier: ^9.24.0 - version: 9.30.1(jiti@1.21.7) + version: 9.38.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.30.1(jiti@1.21.7)) + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.1(eslint@9.30.1(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint@9.38.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.3)(typescript@5.8.3)(yaml@2.8.0) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.1) tsx: specifier: ^4.19.2 version: 4.20.3 @@ -394,25 +849,25 @@ importers: version: 5.8.3 vite: specifier: ^6.2.6 - version: 6.3.5(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) + version: 6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.8.3)(vite@6.3.5(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0)) + version: 5.1.4(typescript@5.8.3)(vite@6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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.1) - ../typescript/packages/x402-hono: + ../typescript/packages/legacy/x402-hono: dependencies: '@coinbase/cdp-sdk': specifier: ^1.22.0 - version: 1.38.0(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10) + version: 1.38.4(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@solana/kit': specifier: ^2.1.1 version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) hono: specifier: ^4.7.1 - version: 4.8.3 + version: 4.10.2 viem: specifier: ^2.21.26 version: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) @@ -425,34 +880,34 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.30.1 + version: 9.38.0 '@types/node': specifier: ^22.13.4 version: 22.16.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) eslint: specifier: ^9.24.0 - version: 9.30.1(jiti@1.21.7) + version: 9.38.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.30.1(jiti@1.21.7)) + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.1(eslint@9.30.1(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint@9.38.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.3)(typescript@5.8.3)(yaml@2.8.0) + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.1) tsx: specifier: ^4.19.2 version: 4.20.3 @@ -461,25 +916,25 @@ importers: version: 5.8.3 vite: specifier: ^6.2.6 - version: 6.3.5(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) + version: 6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.8.3)(vite@6.3.5(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0)) + version: 5.1.4(typescript@5.8.3)(vite@6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1)) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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.1) - ../typescript/packages/x402-next: + ../typescript/packages/legacy/x402-next: dependencies: '@coinbase/cdp-sdk': specifier: ^1.22.0 - version: 1.38.0(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10) + version: 1.38.4(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@solana/kit': specifier: ^2.1.1 version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) next: specifier: ^15.0.0 - version: 15.3.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 15.5.6(@babel/core@7.28.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) viem: specifier: ^2.21.26 version: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) @@ -490,88 +945,293 @@ importers: specifier: ^3.24.2 version: 3.25.71 devDependencies: - '@eslint/js': - specifier: ^9.24.0 - version: 9.30.1 + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 + '@types/node': + specifier: ^22.13.4 + version: 22.16.0 + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.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.3)(typescript@5.8.3)(yaml@2.8.1) + tsx: + specifier: ^4.19.2 + version: 4.20.3 + typescript: + specifier: ^5.7.3 + version: 5.8.3 + vite: + specifier: ^6.2.6 + version: 6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.8.3)(vite@6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1)) + vitest: + specifier: ^3.0.5 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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.1) + + ../typescript/packages/mechanisms/evm: + dependencies: + '@x402/core': + specifier: workspace:* + version: link:../../core + viem: + specifier: ^2.21.26 + version: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + zod: + specifier: ^3.24.2 + version: 3.25.71 + devDependencies: + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 + '@types/node': + specifier: ^22.13.4 + version: 22.16.0 + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.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.3)(typescript@5.8.3)(yaml@2.8.1) + tsx: + specifier: ^4.19.2 + version: 4.20.3 + typescript: + specifier: ^5.7.3 + version: 5.8.3 + vite: + specifier: ^6.2.6 + version: 6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.8.3)(vite@6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1)) + vitest: + specifier: ^3.0.5 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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.1) + + ../typescript/packages/mechanisms/svm: + dependencies: + '@x402/core': + specifier: workspace:* + version: link:../../core + zod: + specifier: ^3.24.2 + version: 3.25.71 + devDependencies: + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 + '@types/node': + specifier: ^22.13.4 + version: 22.16.0 + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.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.3)(typescript@5.8.3)(yaml@2.8.1) + tsx: + specifier: ^4.19.2 + version: 4.20.3 + typescript: + specifier: ^5.7.3 + version: 5.8.3 + vite: + specifier: ^6.2.6 + version: 6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.8.3)(vite@6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1)) + vitest: + specifier: ^3.0.5 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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.1) + + clients/fetch: + dependencies: + '@x402/core': + specifier: workspace:* + version: link:../../../typescript/packages/core + '@x402/evm': + specifier: workspace:* + version: link:../../../typescript/packages/mechanisms/evm + '@x402/fetch': + specifier: workspace:* + version: link:../../../typescript/packages/http/fetch + axios: + specifier: ^1.7.9 + version: 1.10.0 + dotenv: + specifier: ^16.4.7 + version: 16.6.1 + viem: + specifier: ^2.21.26 + version: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + devDependencies: + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.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.3 + typescript: + specifier: ^5.3.0 + version: 5.8.3 + + facilitators/typescript: + dependencies: + '@x402/core': + specifier: workspace:* + version: link:../../../typescript/packages/core + '@x402/evm': + specifier: workspace:* + version: link:../../../typescript/packages/mechanisms/evm + '@x402/extensions': + specifier: workspace:* + version: link:../../../typescript/packages/extensions + dotenv: + specifier: ^16.4.5 + version: 16.6.1 + express: + specifier: ^4.19.2 + version: 4.21.2 + viem: + specifier: ^2.21.54 + version: 2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@4.1.12) + devDependencies: + '@types/express': + specifier: ^4.17.21 + version: 4.17.23 '@types/node': - specifier: ^22.13.4 + specifier: ^22.10.1 version: 22.16.0 - '@typescript-eslint/eslint-plugin': - specifier: ^8.29.1 - version: 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) - '@typescript-eslint/parser': - specifier: ^8.29.1 - version: 8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) eslint: - specifier: ^9.24.0 - version: 9.30.1(jiti@1.21.7) - eslint-plugin-import: - specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@1.21.7)) - eslint-plugin-jsdoc: - specifier: ^50.6.9 - version: 50.8.0(eslint@9.30.1(jiti@1.21.7)) - eslint-plugin-prettier: - specifier: ^5.2.6 - version: 5.5.1(eslint@9.30.1(jiti@1.21.7))(prettier@3.5.2) + specifier: ^9.15.0 + version: 9.38.0(jiti@1.21.7) prettier: - specifier: 3.5.2 + specifier: ^3.3.3 version: 3.5.2 - tsup: - specifier: ^8.4.0 - 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.3 typescript: - specifier: ^5.7.3 + specifier: ^5.7.2 version: 5.8.3 - vite: - specifier: ^6.2.6 - version: 6.3.5(@types/node@22.16.0)(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.8.3)(vite@6.3.5(@types/node@22.16.0)(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.16.0)(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) - clients/axios: + legacy/clients/axios: dependencies: axios: specifier: ^1.7.9 - version: 1.10.0 + version: 1.12.2 dotenv: specifier: ^16.5.0 version: 16.6.1 viem: specifier: ^2.21.26 - version: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + version: 2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@4.1.12) x402-axios: specifier: workspace:* - version: link:../../../typescript/packages/x402-axios + version: link:../../../../typescript/packages/legacy/x402-axios devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.30.1 + version: 9.38.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) eslint: specifier: ^9.24.0 - version: 9.30.1(jiti@1.21.7) + version: 9.38.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.30.1(jiti@1.21.7)) + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.1(eslint@9.30.1(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint@9.38.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 @@ -582,42 +1242,42 @@ importers: specifier: ^5.3.0 version: 5.8.3 - clients/fetch: + legacy/clients/fetch: dependencies: axios: specifier: ^1.7.9 - version: 1.10.0 + version: 1.12.2 dotenv: specifier: ^16.4.7 version: 16.6.1 viem: specifier: ^2.21.26 - version: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + version: 2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@4.1.12) x402-fetch: specifier: workspace:* - version: link:../../../typescript/packages/x402-fetch + version: link:../../../../typescript/packages/legacy/x402-fetch devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.30.1 + version: 9.38.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) eslint: specifier: ^9.24.0 - version: 9.30.1(jiti@1.21.7) + version: 9.38.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.30.1(jiti@1.21.7)) + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.1(eslint@9.30.1(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint@9.38.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 @@ -628,11 +1288,11 @@ importers: specifier: ^5.3.0 version: 5.8.3 - servers/express: + legacy/servers/express: dependencies: '@coinbase/x402': specifier: workspace:* - version: link:../../../typescript/packages/coinbase-x402 + version: link:../../../../typescript/packages/legacy/coinbase-x402 dotenv: specifier: ^16.6.1 version: 16.6.1 @@ -641,38 +1301,38 @@ importers: version: 4.21.2 x402-express: specifier: workspace:* - version: link:../../../typescript/packages/x402-express + version: link:../../../../typescript/packages/legacy/x402-express devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.30.1 + version: 9.38.0 '@types/express': specifier: ^5.0.1 version: 5.0.3 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) eslint: specifier: ^9.24.0 - version: 9.30.1(jiti@1.21.7) + version: 9.38.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.30.1(jiti@1.21.7)) + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.1(eslint@9.30.1(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint@9.38.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsup: specifier: ^7.2.0 - version: 7.3.0(postcss@8.5.6)(ts-node@10.9.2(@types/node@22.16.0)(typescript@5.8.3))(typescript@5.8.3) + version: 7.3.0(postcss@8.5.6)(typescript@5.8.3) tsx: specifier: ^4.7.0 version: 4.20.3 @@ -680,48 +1340,48 @@ importers: specifier: ^5.3.0 version: 5.8.3 - servers/hono: + legacy/servers/hono: dependencies: '@hono/node-server': specifier: ^1.13.8 - version: 1.15.0(hono@4.8.3) + version: 1.19.5(hono@4.10.2) dotenv: specifier: ^16.4.7 version: 16.6.1 hono: specifier: ^4.7.1 - version: 4.8.3 + version: 4.10.2 x402-hono: specifier: workspace:* - version: link:../../../typescript/packages/x402-hono + version: link:../../../../typescript/packages/legacy/x402-hono devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.30.1 + version: 9.38.0 '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) eslint: specifier: ^9.24.0 - version: 9.30.1(jiti@1.21.7) + version: 9.38.0(jiti@1.21.7) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.30.1(jiti@1.21.7)) + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.1(eslint@9.30.1(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint@9.38.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 tsup: specifier: ^7.2.0 - version: 7.3.0(postcss@8.5.6)(ts-node@10.9.2(@types/node@22.16.0)(typescript@5.8.3))(typescript@5.8.3) + version: 7.3.0(postcss@8.5.6)(typescript@5.8.3) tsx: specifier: ^4.7.0 version: 4.20.3 @@ -729,33 +1389,33 @@ importers: specifier: ^5.3.0 version: 5.8.3 - servers/next: + legacy/servers/next: dependencies: '@coinbase/x402': specifier: workspace:* - version: link:../../../typescript/packages/coinbase-x402 + version: link:../../../../typescript/packages/legacy/coinbase-x402 '@heroicons/react': specifier: ^2.2.0 - version: 2.2.0(react@19.1.0) + version: 2.2.0(react@19.2.0) next: - specifier: canary - version: 15.4.0-canary.113(@babel/core@7.28.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: ^15.1.7 + version: 15.5.6(@babel/core@7.28.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react: specifier: ^19.0.0 - version: 19.1.0 + version: 19.2.0 react-dom: specifier: ^19.0.0 - version: 19.1.0(react@19.1.0) + version: 19.2.0(react@19.2.0) viem: specifier: ^2.21.26 - version: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + version: 2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@4.1.12) x402-next: specifier: workspace:* - version: link:../../../typescript/packages/x402-next + version: link:../../../../typescript/packages/legacy/x402-next devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.30.1 + version: 9.38.0 '@svgr/webpack': specifier: ^8.1.0 version: 8.1.0(typescript@5.8.3) @@ -764,16 +1424,16 @@ importers: version: 20.19.4 '@types/react': specifier: ^19 - version: 19.1.8 + version: 19.2.2 '@types/react-dom': specifier: ^19 - version: 19.1.6(@types/react@19.1.8) + version: 19.2.2(@types/react@19.2.2) '@typescript-eslint/eslint-plugin': specifier: ^8.29.1 - version: 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) buffer: specifier: ^6.0.3 version: 6.0.3 @@ -782,19 +1442,19 @@ importers: version: 3.12.1 eslint: specifier: ^9.24.0 - version: 9.30.1(jiti@1.21.7) + version: 9.38.0(jiti@1.21.7) eslint-config-next: specifier: 15.1.7 - version: 15.1.7(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + version: 15.1.7(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) eslint-plugin-import: specifier: ^2.31.0 - version: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@1.21.7)) + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-jsdoc: specifier: ^50.6.9 - version: 50.8.0(eslint@9.30.1(jiti@1.21.7)) + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) eslint-plugin-prettier: specifier: ^5.2.6 - version: 5.5.1(eslint@9.30.1(jiti@1.21.7))(prettier@3.5.2) + version: 5.5.4(eslint@9.38.0(jiti@1.21.7))(prettier@3.5.2) postcss: specifier: ^8 version: 8.5.6 @@ -806,11 +1466,69 @@ importers: version: 3.0.0 tailwindcss: specifier: ^3.4.1 - version: 3.4.17(ts-node@10.9.2(@types/node@20.19.4)(typescript@5.8.3)) + version: 3.4.18(tsx@4.20.3)(yaml@2.8.1) typescript: specifier: ^5 version: 5.8.3 + servers/express: + dependencies: + '@x402/core': + specifier: workspace:* + version: link:../../../typescript/packages/core + '@x402/evm': + specifier: workspace:* + version: link:../../../typescript/packages/mechanisms/evm + '@x402/express': + specifier: workspace:* + version: link:../../../typescript/packages/http/express + '@x402/extensions': + specifier: workspace:* + version: link:../../../typescript/packages/extensions + dotenv: + specifier: ^16.6.1 + version: 16.6.1 + express: + specifier: ^4.18.2 + version: 4.21.2 + devDependencies: + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 + '@types/express': + specifier: ^5.0.1 + version: 5.0.3 + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.0(jiti@1.21.7))(prettier@3.5.2) + prettier: + specifier: 3.5.2 + version: 3.5.2 + tsup: + specifier: ^7.2.0 + version: 7.3.0(postcss@8.5.6)(typescript@5.8.3) + tsx: + specifier: ^4.7.0 + version: 4.20.3 + typescript: + specifier: ^5.3.0 + version: 5.8.3 + packages: '@adraffy/ens-normalize@1.11.0': @@ -820,10 +1538,6 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - '@asamuzakjp/css-color@3.2.0': resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==} @@ -831,16 +1545,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.28.4': + resolution: {integrity: sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==} engines: {node: '>=6.9.0'} - '@babel/core@7.28.0': - resolution: {integrity: sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==} + '@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.0': - resolution: {integrity: sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==} + '@babel/generator@7.28.3': + resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} engines: {node: '>=6.9.0'} '@babel/helper-annotate-as-pure@7.27.3': @@ -851,8 +1565,8 @@ packages: resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} engines: {node: '>=6.9.0'} - '@babel/helper-create-class-features-plugin@7.27.1': - resolution: {integrity: sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==} + '@babel/helper-create-class-features-plugin@7.28.3': + resolution: {integrity: sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -880,8 +1594,8 @@ packages: resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.27.3': - resolution: {integrity: sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==} + '@babel/helper-module-transforms@7.28.3': + resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -922,16 +1636,16 @@ packages: resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helper-wrap-function@7.27.1': - resolution: {integrity: sha512-NFJK2sHUvrjo8wAU/nQTWU890/zB2jj0qBcCbZbbf+005cAsv6tMjXz31fBign6M5ov1o0Bllu+9nbqkfsjjJQ==} + '@babel/helper-wrap-function@7.28.3': + resolution: {integrity: sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.27.6': - resolution: {integrity: sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==} + '@babel/helpers@7.28.4': + resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} engines: {node: '>=6.9.0'} - '@babel/parser@7.28.0': - resolution: {integrity: sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==} + '@babel/parser@7.28.4': + resolution: {integrity: sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==} engines: {node: '>=6.0.0'} hasBin: true @@ -959,8 +1673,8 @@ packages: peerDependencies: '@babel/core': ^7.13.0 - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.27.1': - resolution: {integrity: sha512-6BpaYGDavZqkI6yT+KSPdpZFfpnd68UKXbcjI9pJ13pvHhPrCKWOOLp+ysvMeA+DxnhuPpgIaRpxRxo5A9t5jw==} + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3': + resolution: {integrity: sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1025,8 +1739,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 @@ -1037,14 +1751,14 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-class-static-block@7.27.1': - resolution: {integrity: sha512-s734HmYU78MVzZ++joYM+NkJusItbdRcbm+AGRgJCt3iA+yux0QpD9cBVdz3tKyrjVYWRl7j0mHSmv4lhV0aoA==} + '@babel/plugin-transform-class-static-block@7.28.3': + resolution: {integrity: sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 - '@babel/plugin-transform-classes@7.28.0': - resolution: {integrity: sha512-IjM1IoJNw72AZFlj33Cu8X0q2XK/6AaVC3jQu+cgQ5lThWD5ajnuUAml80dqRmOhmPkTH8uAwnpMu9Rvj0LTRA==} + '@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 @@ -1187,8 +1901,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 @@ -1265,8 +1979,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-regenerator@7.28.0': - resolution: {integrity: sha512-LOAozRVbqxEVjSKfhGnuLoE4Kz4Oc5UJzuvFUhSsQzdCdaAQu06mG8zDv2GFSerM62nImUZ7K92vxnQcLSDlCQ==} + '@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 @@ -1343,8 +2057,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/preset-env@7.28.0': - resolution: {integrity: sha512-VmaxeGOwuDqzLl5JUkIRM1X2Qu2uKGxHEQWh+cvvbl7JuJRgKGJSfsEF/bUaxFhJl/XAyxBe7q7qSuTbKFuCyg==} + '@babel/preset-env@7.28.3': + resolution: {integrity: sha512-ROiDcM+GbYVPYBOeCR6uBXKkQpBExLl8k9HO1ygXEyds39j+vCCsjmj7S8GOniZQlEs81QlkdJZe76IpLSiqpg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1366,27 +2080,30 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/runtime@7.27.6': - resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==} + '@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.0': - resolution: {integrity: sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==} + '@babel/traverse@7.28.4': + resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.0': - resolution: {integrity: sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==} + '@babel/types@7.28.4': + resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} engines: {node: '>=6.9.0'} - '@coinbase/cdp-sdk@1.38.0': - resolution: {integrity: sha512-q9DVmzTqhS0WFuU/IfSahp0wvdy2CAwftl2f110z90w5BHLFhUlK9OKFmIuZMZ3dCo6GK6IWq0IlQERdezruSg==} + '@base-org/account@1.1.1': + resolution: {integrity: sha512-IfVJPrDPhHfqXRDb89472hXkpvJuQQR7FDI9isLPHEqSYt/45whIoBxSPgZ0ssTt379VhQo4+87PWI1DoLSfAQ==} - '@coinbase/onchainkit@0.38.15': - resolution: {integrity: sha512-RlZ2I7XlNyuVaWjF7/1WY6LzQTaRH2bTitb1wfwTEfxM8a1matfitpNZ2vAVLjRqDvHvgzegfyW6xxS+dUuCxA==} + '@coinbase/cdp-sdk@1.38.4': + resolution: {integrity: sha512-xVvfluaGt0NxNmjElP3C1yI6KnsGwihabdXj+qNtjjsSmd/Ha2V3gAiCyNrrYOqIORn4mpC2jgu2fUFEDaMpaw==} + + '@coinbase/onchainkit@0.38.19': + resolution: {integrity: sha512-4uiujoTO5/8/dpWVZoTlBC7z0Y1N5fgBYDR6pKN/r6a8pX83ObUuOSGhSzJ8Xbu8NpPU6TXX+VuzLiwiLg/irg==} peerDependencies: react: ^18 || ^19 react-dom: ^18 || ^19 @@ -1394,8 +2111,8 @@ packages: '@coinbase/wallet-sdk@3.9.3': resolution: {integrity: sha512-N/A2DRIf0Y3PHc1XAMvbBUu4zisna6qAdqABMZwBMNEfWrXpAwx16pZGkYCLGE+Rvv1edbcB2LYDRnACNcmCiw==} - '@coinbase/wallet-sdk@4.3.3': - resolution: {integrity: sha512-h8gMLQNvP5TIJVXFOyQZaxbi1Mg5alFR4Z2/PEIngdyXZEoQGcVhzyQGuDa3t9zpllxvqfAaKfzDhsfCo+nhSQ==} + '@coinbase/wallet-sdk@4.3.6': + resolution: {integrity: sha512-4q8BNG1ViL4mSAAvPAtpwlOs1gpC+67eQtgIwNvT3xyeyFFd+guwkc8bcX5rTmQhXpqnhzC4f0obACbP9CqMSA==} '@craftamap/esbuild-plugin-html@0.9.0': resolution: {integrity: sha512-V5LFrcGXQWU1SSzYPwxEFjF8IjeXW0oTKh5c0xyhGuTNoEnjgJRNSX83HnZ5TTAutJfo/MAyWA4Z9/fIwbMhUQ==} @@ -1403,12 +2120,8 @@ packages: peerDependencies: esbuild: '>=0.15.10' - '@cspotcode/source-map-support@0.8.1': - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - - '@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': @@ -1418,8 +2131,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 @@ -1435,20 +2148,20 @@ packages: resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} engines: {node: '>=18'} - '@ecies/ciphers@0.2.3': - resolution: {integrity: sha512-tapn6XhOueMwht3E2UzY0ZZjYokdaw9XtL9kEyjhQ/Fb9vL9xTFbOaI+fV0AWvTpYu4BNloC6getKW6NtSg4mA==} + '@ecies/ciphers@0.2.4': + resolution: {integrity: sha512-t+iX+Wf5nRKyNzk8dviW3Ikb/280+aEJAnw9YXvCp2tYGPSkMki+NRY+8aNLmVFv3eNtMdvViPNOPxS8SZNP+w==} engines: {bun: '>=1', deno: '>=2', node: '>=16'} peerDependencies: '@noble/ciphers': ^1.0.0 - '@emnapi/core@1.4.3': - resolution: {integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==} + '@emnapi/core@1.6.0': + resolution: {integrity: sha512-zq/ay+9fNIJJtJiZxdTnXS20PllcYMX3OE23ESc4HK/bdYu3cOWYVhsOhVnXALfU/uqJIxn5NBPd9z4v+SfoSg==} - '@emnapi/runtime@1.4.3': - resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} + '@emnapi/runtime@1.6.0': + resolution: {integrity: sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA==} - '@emnapi/wasi-threads@1.0.2': - resolution: {integrity: sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==} + '@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==} @@ -1742,46 +2455,42 @@ packages: 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 - '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/config-array@0.21.0': - resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/config-helpers@0.3.0': - resolution: {integrity: sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==} + '@eslint/config-array@0.21.1': + resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.14.0': - resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==} + '@eslint/config-helpers@0.4.1': + resolution: {integrity: sha512-csZAzkNhsgwb0I/UAV6/RGFTbiakPCf0ZrGmrIxQpYvGZ00PhTkSnyKNolphgIvmnJeGw6rcGVEXfTzUnFuEvw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.15.1': - resolution: {integrity: sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==} + '@eslint/core@0.16.0': + resolution: {integrity: sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==} 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.30.1': - resolution: {integrity: sha512-zXhuECFlyep42KZUhWjfvsmXGX39W8K8LFb8AWXM9gSV9dQB+MrJGLKvW6Zw0Ggnbpw0VHTtrhFXYe3Gym18jg==} + '@eslint/js@9.38.0': + resolution: {integrity: sha512-UZ1VpFvXf9J06YG9xQBdnzU+kthors6KjhMAl6f4gH4usHyh31rUf2DLGInT8RFYIReYXNSydgPY0V2LuWgl7A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/object-schema@2.1.6': - resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.3.3': - resolution: {integrity: sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag==} + '@eslint/plugin-kit@0.4.0': + resolution: {integrity: sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ethereumjs/common@3.2.0': @@ -1800,24 +2509,38 @@ packages: resolution: {integrity: sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==} engines: {node: '>=14'} - '@farcaster/frame-core@0.1.8': - resolution: {integrity: sha512-Y0JATQXa/iaqH3pCp8Dby4iCQbwqw7JJaGtfzUazdr7R+zs3EDP8DYQCkqJu6iGjE9gqgecB+b+DOZpnqMTDNw==} + '@farcaster/frame-sdk@0.1.12': + resolution: {integrity: sha512-qlikvkxsrsvKGutr3PM3Yvsuni2Fku15aPagrCyHZWbYAJrZ4mRJM6u9S8eLAXMMnYd9gJ9yor6COYgmZMBOgQ==} + engines: {node: '>=22.11.0'} + + '@farcaster/miniapp-core@0.4.1': + resolution: {integrity: sha512-20FxHTRToYUKx7CQ8PvIy9OoQ6XjdmF1pRMS7dsj37qdqjVDeEkYoK8yXwnoReZoJRcYwIg8P3i6V8bTWNR5mg==} - '@farcaster/frame-sdk@0.0.60': - resolution: {integrity: sha512-MHQwdFT1VPe3kS0NvnORBPb/DQXr8qpdSDgIgfrdVCB8byQ5uFELlr3gQMuFYFyLFQVXgbMl75z8O6+hvorqow==} + '@farcaster/miniapp-sdk@0.2.1': + resolution: {integrity: sha512-2SnDeOtDdlN1lGQt7UyH2jkrZRQDOkmhcrlzNWazYChyPh9XfV8+9fMS+Lr/E2pEws9Q40Xl9POrCzdpUC19lg==} - '@farcaster/frame-wagmi-connector@0.0.53': - resolution: {integrity: sha512-+fonXzzj3KxTeUHbtt7lZUC4v/MhC2Y2KpQw7WcVamiDwedm+jTMqBIdrMrWRej/HSWrBQ1rDIOlsWxnv9CDng==} + '@farcaster/miniapp-wagmi-connector@1.1.0': + resolution: {integrity: sha512-gf0nDx9nNJ6hJXbFBCgiTitb0eEqBvCU/njcyTXf7ebZhT0pzOrarOod2dkeisU5Py+WWjFyOVcqmeo4G3IvDA==} peerDependencies: - '@farcaster/frame-sdk': ^0.0.64 + '@farcaster/miniapp-sdk': ^0.2.0 '@wagmi/core': ^2.14.1 viem: ^2.21.55 - '@farcaster/quick-auth@0.0.5': - resolution: {integrity: sha512-Z8hWz/7c33zlmII2AJHja/Wz0C03mm2o+CEBtBylmiun1wC4FMgx1Fal699VQvBUG1lpcJ662WxuRNxKogktDw==} + '@farcaster/quick-auth@0.0.6': + resolution: {integrity: sha512-tiZndhpfDtEhaKlkmS5cVDuS+A/tafqZT3y9I44rC69m3beJok6e8dIH2JhxVy3EvOWTyTBnrmNn6GOOh+qK6A==} + peerDependencies: + typescript: 5.8.3 + + '@farcaster/quick-auth@0.0.8': + resolution: {integrity: sha512-NRIq1BcbcQCC6xBF5owfckkY00xKQVpqhpLNl5rICVpl0xeDsiVbkenIrHaUuyjtCK2W28YVc2ZCFRyz9ERHKg==} 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: @@ -1828,8 +2551,8 @@ packages: peerDependencies: react: '>= 16 || ^19.0.0-rc' - '@hono/node-server@1.15.0': - resolution: {integrity: sha512-MjmK4l5N4dQpZ9OSWN0tCj7ejuc7WvuWMzSKtc89bnknJykAeHxzRigXBTYZk85H6Awrii6RM59iUiUluApu2A==} + '@hono/node-server@1.19.5': + resolution: {integrity: sha512-iBuhh+uaaggeAuf+TftcjZyWh2GEgZcVGXkNtskLVoWaXhnJtC5HLHrU8W1KHDoucqO1MswwglmkWLFyiDn4WQ==} engines: {node: '>=18.14.1'} peerDependencies: hono: ^4 @@ -1838,134 +2561,140 @@ 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/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.2': - resolution: {integrity: sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==} + '@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.2': - resolution: {integrity: sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==} + '@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.1.0': - resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==} + '@img/sharp-libvips-darwin-arm64@1.2.3': + resolution: {integrity: sha512-QzWAKo7kpHxbuHqUC28DZ9pIKpSi2ts2OJnoIGI26+HMgq92ZZ4vk8iJd4XsxN+tYfNJxzH6W62X5eTcsBymHw==} cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.1.0': - resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==} + '@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.1.0': - resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==} + '@img/sharp-libvips-linux-arm64@1.2.3': + resolution: {integrity: sha512-I4RxkXU90cpufazhGPyVujYwfIm9Nk1QDEmiIsaPwdnm013F7RIceaCc87kAH+oUB1ezqEvC6ga4m7MSlqsJvQ==} cpu: [arm64] os: [linux] - '@img/sharp-libvips-linux-arm@1.1.0': - resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==} + '@img/sharp-libvips-linux-arm@1.2.3': + resolution: {integrity: sha512-x1uE93lyP6wEwGvgAIV0gP6zmaL/a0tGzJs/BIDDG0zeBhMnuUPm7ptxGhUbcGs4okDJrk4nxgrmxpib9g6HpA==} cpu: [arm] os: [linux] - '@img/sharp-libvips-linux-ppc64@1.1.0': - resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==} + '@img/sharp-libvips-linux-ppc64@1.2.3': + resolution: {integrity: sha512-Y2T7IsQvJLMCBM+pmPbM3bKT/yYJvVtLJGfCs4Sp95SjvnFIjynbjzsa7dY1fRJX45FTSfDksbTp6AGWudiyCg==} cpu: [ppc64] os: [linux] - '@img/sharp-libvips-linux-s390x@1.1.0': - resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==} + '@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.1.0': - resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==} + '@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.1.0': - resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==} + '@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.1.0': - resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==} + '@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.2': - resolution: {integrity: sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==} + '@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.2': - resolution: {integrity: sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==} + '@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-s390x@0.34.2': - resolution: {integrity: sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==} + '@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.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.2': - resolution: {integrity: sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==} + '@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.2': - resolution: {integrity: sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==} + '@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.2': - resolution: {integrity: sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==} + '@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.2': - resolution: {integrity: sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==} + '@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.2': - resolution: {integrity: sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==} + '@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.2': - resolution: {integrity: sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==} + '@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.2': - resolution: {integrity: sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==} + '@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] @@ -1974,27 +2703,27 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} - '@jridgewell/gen-mapping@0.3.12': - resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==} + '@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'} - '@jridgewell/sourcemap-codec@1.5.4': - resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==} + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.29': - resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@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.0': - resolution: {integrity: sha512-L2qyoZSQClcBmq0qajBVbhYEcG6iK0XfLn66ifLe/RfC0/ihpc+pl0Wdn8bJ8o+hj38cG0fGXRgSS20MuXn7qA==} + '@lit/reactive-element@2.1.1': + resolution: {integrity: sha512-N+dm5PAYdQ8e6UlywyyrgI2t++wFGXfHx+dSJ1oBrg6FAxUj40jId++EaRm80MKX5JnlH1sBsyZ5h0bcZKemCg==} '@metamask/eth-json-rpc-provider@1.0.1': resolution: {integrity: sha512-whiUMPlAOrVGmX8aKYVPvlKyG4CpQXiNNyt74vE1xb5sPvmx5oA7B/kOi/JdBvhGQq97U1/AVdXEdk2zkP8qyA==} @@ -2027,6 +2756,10 @@ 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==} @@ -2034,8 +2767,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: '*' @@ -2043,16 +2779,20 @@ 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.8.1': + resolution: {integrity: sha512-DIbsNUyqWLFgqJlZxi1OOCMYvI23GqFCvNJAtzv8/WXWzJfnJnvp1M24j7VvUe3URBi3S86UgQ7+7aWU9p/cnQ==} + engines: {node: ^18.18 || ^20.14 || >=22} + '@metamask/utils@5.0.2': resolution: {integrity: sha512-yfmE79bRQtnMzarnKfX7AEJBwFTxvTyw3nBQlu/5rmGXrjAeAMltoGxO62TFurxrQAFMNa/fEjIHNvungZp0+g==} engines: {node: '>=14.0.0'} @@ -2065,110 +2805,59 @@ packages: resolution: {integrity: sha512-w8CVbdkDrVXFJbfBSlDfafDR6BAkpDmv1bC1UJVCoVny5tW2RKAdn9i68Xf7asYT4TnUhl/hN4zfUiKQq9II4g==} engines: {node: '>=16.0.0'} - '@napi-rs/wasm-runtime@0.2.11': - resolution: {integrity: sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==} + '@napi-rs/wasm-runtime@0.2.12': + resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} - '@next/env@15.3.4': - resolution: {integrity: sha512-ZkdYzBseS6UjYzz6ylVKPOK+//zLWvD6Ta+vpoye8cW11AjiQjGYVibF0xuvT4L0iJfAPfZLFidaEzAOywyOAQ==} - - '@next/env@15.4.0-canary.113': - resolution: {integrity: sha512-+HC7oDcADo3Xh4luInUBRv8x96fHh0vDjcsUN8ecZRcd+2gc37CgRcdYJofWnLnIbEsuIV6U8LwYYhJRw9N1nw==} + '@next/env@15.5.6': + resolution: {integrity: sha512-3qBGRW+sCGzgbpc5TS1a0p7eNxnOarGVQhZxfvTdnV0gFI61lX7QNtQ4V1TSREctXzYn5NetbUsLvyqwLFJM6Q==} '@next/eslint-plugin-next@15.1.7': resolution: {integrity: sha512-kRP7RjSxfTO13NE317ek3mSGzoZlI33nc/i5hs1KaWpK+egs85xg0DJ4p32QEiHnR0mVjuUfhRIun7awqfL7pQ==} - '@next/swc-darwin-arm64@15.3.4': - resolution: {integrity: sha512-z0qIYTONmPRbwHWvpyrFXJd5F9YWLCsw3Sjrzj2ZvMYy9NPQMPZ1NjOJh4ojr4oQzcGYwgJKfidzehaNa1BpEg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@next/swc-darwin-arm64@15.4.0-canary.113': - resolution: {integrity: sha512-Rug3HXDrkjlfrIiREBwWjC3DWHWeSjHDYcWjjwnsj5jlUH+HTzyJCa1mSQR3vYiR8cES1CmLhYW5ELVyrDIoMw==} + '@next/swc-darwin-arm64@15.5.6': + resolution: {integrity: sha512-ES3nRz7N+L5Umz4KoGfZ4XX6gwHplwPhioVRc25+QNsDa7RtUF/z8wJcbuQ2Tffm5RZwuN2A063eapoJ1u4nPg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@15.3.4': - resolution: {integrity: sha512-Z0FYJM8lritw5Wq+vpHYuCIzIlEMjewG2aRkc3Hi2rcbULknYL/xqfpBL23jQnCSrDUGAo/AEv0Z+s2bff9Zkw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@next/swc-darwin-x64@15.4.0-canary.113': - resolution: {integrity: sha512-djM2ai6MYbcop28H0y2VKucmdSvoaVWrA5N8eZ1SlMdwqfIaBeihosr5MFahqMRS3MKe43Cny6bgdJ3WAIhTDA==} + '@next/swc-darwin-x64@15.5.6': + resolution: {integrity: sha512-JIGcytAyk9LQp2/nuVZPAtj8uaJ/zZhsKOASTjxDug0SPU9LAM3wy6nPU735M1OqacR4U20LHVF5v5Wnl9ptTA==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@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-gnu@15.4.0-canary.113': - resolution: {integrity: sha512-LPAX6qvaZEhkws1Vg8KL/KJPs2NqepaoqvEa+9iqqKWAx16Pz0nmerNo7A1pSws+6IP4YDrc6qGxznpZXRyQiA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-arm64-musl@15.3.4': - resolution: {integrity: sha512-wFyZ7X470YJQtpKot4xCY3gpdn8lE9nTlldG07/kJYexCUpX1piX+MBfZdvulo+t1yADFVEuzFfVHfklfEx8kw==} + '@next/swc-linux-arm64-gnu@15.5.6': + resolution: {integrity: sha512-qvz4SVKQ0P3/Im9zcS2RmfFL/UCQnsJKJwQSkissbngnB/12c6bZTCB0gHTexz1s6d/mD0+egPKXAIRFVS7hQg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@15.4.0-canary.113': - resolution: {integrity: sha512-8/a0Fb41O0ArrMIuo20v5iS3e9j602eUPNLtOjrJImyQ0SLRL5N8BYlz6LTW56cYJcNVl/8MLfZY1fTz7n157w==} + '@next/swc-linux-arm64-musl@15.5.6': + resolution: {integrity: sha512-FsbGVw3SJz1hZlvnWD+T6GFgV9/NYDeLTNQB2MXoPN5u9VA9OEDy6fJEfePfsUKAhJufFbZLgp0cPxMuV6SV0w==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@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-gnu@15.4.0-canary.113': - resolution: {integrity: sha512-Ubil9yLdDRmVwRXsbczSeQPGaH5Wgqa2I7l4nJsgzdvJcdcVEH/0MRNy1MIGQXfnB5mLofZ7YFDWaL/yTdDP2Q==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-linux-x64-musl@15.3.4': - resolution: {integrity: sha512-Cf8sr0ufuC/nu/yQ76AnarbSAXcwG/wj+1xFPNbyNo8ltA6kw5d5YqO8kQuwVIxk13SBdtgXrNyom3ZosHAy4A==} + '@next/swc-linux-x64-gnu@15.5.6': + resolution: {integrity: sha512-3QnHGFWlnvAgyxFxt2Ny8PTpXtQD7kVEeaFat5oPAHHI192WKYB+VIKZijtHLGdBBvc16tiAkPTDmQNOQ0dyrA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@15.4.0-canary.113': - resolution: {integrity: sha512-EhPvX+yqDKGwVaTQuosGujUZy1cjbIuZ+FU4obu4hFjgjrlps9nxoS6vM/wHXitzN1hdfg0HiUsFOl3KZWd4fw==} + '@next/swc-linux-x64-musl@15.5.6': + resolution: {integrity: sha512-OsGX148sL+TqMK9YFaPFPoIaJKbFJJxFzkXZljIgA9hjMjdruKht6xDCEv1HLtlLNfkx3c5w2GLKhj7veBQizQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-win32-arm64-msvc@15.3.4': - resolution: {integrity: sha512-ay5+qADDN3rwRbRpEhTOreOn1OyJIXS60tg9WMYTWCy3fB6rGoyjLVxc4dR9PYjEdR2iDYsaF5h03NA+XuYPQQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@next/swc-win32-arm64-msvc@15.4.0-canary.113': - resolution: {integrity: sha512-axV35abh0OJICNaFUaCZtYTrlpJgy2aWTw15PnoY02hps9l4nHP8Ck6fHqOSdzZdshEheNeRxUp3QaHEit2VsQ==} + '@next/swc-win32-arm64-msvc@15.5.6': + resolution: {integrity: sha512-ONOMrqWxdzXDJNh2n60H6gGyKed42Ieu6UTVPZteXpuKbLZTH4G4eBMsr5qWgOBA+s7F+uB4OJbZnrkEDnZ5Fg==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-x64-msvc@15.3.4': - resolution: {integrity: sha512-4kDt31Bc9DGyYs41FTL1/kNpDeHyha2TC0j5sRRoKCyrhNcfZ/nRQkAUlF27mETwm8QyHqIjHJitfcza2Iykfg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - - '@next/swc-win32-x64-msvc@15.4.0-canary.113': - resolution: {integrity: sha512-0/fPimhZefBograEkK8ONIJw0KoZwIVBuPThFNqZv+8w21qfz6sEonNhko65zx119Vtl6aMnipwzxJp+CiUukg==} + '@next/swc-win32-x64-msvc@15.5.6': + resolution: {integrity: sha512-pxK4VIjFRx1MY92UycLOOw7dTdvccWsNETQ0kDHkBlcFH1GrTLUjSiHU1ohrznnux6TqRHgv5oflhfIWZwVROQ==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -2192,10 +2881,18 @@ 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.2': resolution: {integrity: sha512-HxngEd2XUcg9xi20JkwlLCtYwfoFw4JGkuZpT+WlsPD4gB/cxkvTD8fSsoAnphGZhFdZYKeQIPCuFlWPm1uE0g==} engines: {node: ^14.21.3 || >=16} + '@noble/curves@1.9.7': + resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} + engines: {node: ^14.21.3 || >=16} + '@noble/hashes@1.4.0': resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} engines: {node: '>= 16'} @@ -2236,8 +2933,8 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@pkgr/core@0.2.7': - resolution: {integrity: sha512-YLT9Zo3oNPJoBjBc4q8G2mjU4tqIbf5CEOORbUUr48dCD9q3umJ3IPlVqOqDakPfd2HuwccBaqlGhN4Gmr5OWg==} + '@pkgr/core@0.2.9': + resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} '@reown/appkit-common@1.7.8': @@ -2269,111 +2966,121 @@ packages: '@reown/appkit@1.7.8': resolution: {integrity: sha512-51kTleozhA618T1UvMghkhKfaPcc9JlKwLJ5uV+riHyvSoWPKPRIa5A6M1Wano5puNyW0s3fwywhyqTHSilkaA==} - '@rollup/rollup-android-arm-eabi@4.44.1': - resolution: {integrity: sha512-JAcBr1+fgqx20m7Fwe1DxPUl/hPkee6jA6Pl7n1v2EFiktAHenTaXl5aIFjUIEsfn9w3HE4gK1lEgNGMzBDs1w==} + '@rollup/rollup-android-arm-eabi@4.52.5': + resolution: {integrity: sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.44.1': - resolution: {integrity: sha512-RurZetXqTu4p+G0ChbnkwBuAtwAbIwJkycw1n6GvlGlBuS4u5qlr5opix8cBAYFJgaY05TWtM+LaoFggUmbZEQ==} + '@rollup/rollup-android-arm64@4.52.5': + resolution: {integrity: sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.44.1': - resolution: {integrity: sha512-fM/xPesi7g2M7chk37LOnmnSTHLG/v2ggWqKj3CCA1rMA4mm5KVBT1fNoswbo1JhPuNNZrVwpTvlCVggv8A2zg==} + '@rollup/rollup-darwin-arm64@4.52.5': + resolution: {integrity: sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.44.1': - resolution: {integrity: sha512-gDnWk57urJrkrHQ2WVx9TSVTH7lSlU7E3AFqiko+bgjlh78aJ88/3nycMax52VIVjIm3ObXnDL2H00e/xzoipw==} + '@rollup/rollup-darwin-x64@4.52.5': + resolution: {integrity: sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.44.1': - resolution: {integrity: sha512-wnFQmJ/zPThM5zEGcnDcCJeYJgtSLjh1d//WuHzhf6zT3Md1BvvhJnWoy+HECKu2bMxaIcfWiu3bJgx6z4g2XA==} + '@rollup/rollup-freebsd-arm64@4.52.5': + resolution: {integrity: sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.44.1': - resolution: {integrity: sha512-uBmIxoJ4493YATvU2c0upGz87f99e3wop7TJgOA/bXMFd2SvKCI7xkxY/5k50bv7J6dw1SXT4MQBQSLn8Bb/Uw==} + '@rollup/rollup-freebsd-x64@4.52.5': + resolution: {integrity: sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.44.1': - resolution: {integrity: sha512-n0edDmSHlXFhrlmTK7XBuwKlG5MbS7yleS1cQ9nn4kIeW+dJH+ExqNgQ0RrFRew8Y+0V/x6C5IjsHrJmiHtkxQ==} + '@rollup/rollup-linux-arm-gnueabihf@4.52.5': + resolution: {integrity: sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.44.1': - resolution: {integrity: sha512-8WVUPy3FtAsKSpyk21kV52HCxB+me6YkbkFHATzC2Yd3yuqHwy2lbFL4alJOLXKljoRw08Zk8/xEj89cLQ/4Nw==} + '@rollup/rollup-linux-arm-musleabihf@4.52.5': + resolution: {integrity: sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.44.1': - resolution: {integrity: sha512-yuktAOaeOgorWDeFJggjuCkMGeITfqvPgkIXhDqsfKX8J3jGyxdDZgBV/2kj/2DyPaLiX6bPdjJDTu9RB8lUPQ==} + '@rollup/rollup-linux-arm64-gnu@4.52.5': + resolution: {integrity: sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.44.1': - resolution: {integrity: sha512-W+GBM4ifET1Plw8pdVaecwUgxmiH23CfAUj32u8knq0JPFyK4weRy6H7ooxYFD19YxBulL0Ktsflg5XS7+7u9g==} + '@rollup/rollup-linux-arm64-musl@4.52.5': + resolution: {integrity: sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.44.1': - resolution: {integrity: sha512-1zqnUEMWp9WrGVuVak6jWTl4fEtrVKfZY7CvcBmUUpxAJ7WcSowPSAWIKa/0o5mBL/Ij50SIf9tuirGx63Ovew==} + '@rollup/rollup-linux-loong64-gnu@4.52.5': + resolution: {integrity: sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.44.1': - resolution: {integrity: sha512-Rl3JKaRu0LHIx7ExBAAnf0JcOQetQffaw34T8vLlg9b1IhzcBgaIdnvEbbsZq9uZp3uAH+JkHd20Nwn0h9zPjA==} + '@rollup/rollup-linux-ppc64-gnu@4.52.5': + resolution: {integrity: sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.44.1': - resolution: {integrity: sha512-j5akelU3snyL6K3N/iX7otLBIl347fGwmd95U5gS/7z6T4ftK288jKq3A5lcFKcx7wwzb5rgNvAg3ZbV4BqUSw==} + '@rollup/rollup-linux-riscv64-gnu@4.52.5': + resolution: {integrity: sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.44.1': - resolution: {integrity: sha512-ppn5llVGgrZw7yxbIm8TTvtj1EoPgYUAbfw0uDjIOzzoqlZlZrLJ/KuiE7uf5EpTpCTrNt1EdtzF0naMm0wGYg==} + '@rollup/rollup-linux-riscv64-musl@4.52.5': + resolution: {integrity: sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.44.1': - resolution: {integrity: sha512-Hu6hEdix0oxtUma99jSP7xbvjkUM/ycke/AQQ4EC5g7jNRLLIwjcNwaUy95ZKBJJwg1ZowsclNnjYqzN4zwkAw==} + '@rollup/rollup-linux-s390x-gnu@4.52.5': + resolution: {integrity: sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.44.1': - resolution: {integrity: sha512-EtnsrmZGomz9WxK1bR5079zee3+7a+AdFlghyd6VbAjgRJDbTANJ9dcPIPAi76uG05micpEL+gPGmAKYTschQw==} + '@rollup/rollup-linux-x64-gnu@4.52.5': + resolution: {integrity: sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.44.1': - resolution: {integrity: sha512-iAS4p+J1az6Usn0f8xhgL4PaU878KEtutP4hqw52I4IO6AGoyOkHCxcc4bqufv1tQLdDWFx8lR9YlwxKuv3/3g==} + '@rollup/rollup-linux-x64-musl@4.52.5': + resolution: {integrity: sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.44.1': - resolution: {integrity: sha512-NtSJVKcXwcqozOl+FwI41OH3OApDyLk3kqTJgx8+gp6On9ZEt5mYhIsKNPGuaZr3p9T6NWPKGU/03Vw4CNU9qg==} + '@rollup/rollup-openharmony-arm64@4.52.5': + resolution: {integrity: sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.52.5': + resolution: {integrity: sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.44.1': - resolution: {integrity: sha512-JYA3qvCOLXSsnTR3oiyGws1Dm0YTuxAAeaYGVlGpUsHqloPcFjPg+X0Fj2qODGLNwQOAcCiQmHub/V007kiH5A==} + '@rollup/rollup-win32-ia32-msvc@4.52.5': + resolution: {integrity: sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.44.1': - resolution: {integrity: sha512-J8o22LuF0kTe7m+8PvW9wk3/bRq5+mRo5Dqo6+vXb7otCm3TPhYOJqOaQtGU9YMWQSL3krMnoOxMr0+9E6F3Ug==} + '@rollup/rollup-win32-x64-gnu@4.52.5': + resolution: {integrity: sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.52.5': + resolution: {integrity: sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==} 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.14.0': + resolution: {integrity: sha512-WJFej426qe4RWOm9MMtP4V3CV4AucXolQty+GRgAWLgQXmpCuwzs7hEpxxhSc/znXUSxum9d/P/32MW0FlAAlA==} '@safe-global/safe-apps-provider@0.18.6': resolution: {integrity: sha512-4LhMmjPWlIO8TTDC2AwLk44XKXaK6hfBTWyljDm0HQ6TWlOEijVWNrt2s3OCVMSxlXAcEzYfqyu1daHZooTC2Q==} @@ -2417,6 +3124,11 @@ packages: peerDependencies: '@solana/kit': ^2.1.0 + '@solana-program/system@0.8.1': + resolution: {integrity: sha512-71U9Mzdpw8HQtfgfJSL5xKZbLMRnza2Llsfk7gGnmg2waqK+o8MMH4YNma8xXS1UmOBptXIiNvoZ3p7cmOVktg==} + peerDependencies: + '@solana/kit': ^3.0 + '@solana-program/token-2022@0.4.2': resolution: {integrity: sha512-zIpR5t4s9qEU3hZKupzIBxJ6nUV5/UVyIT400tu9vT1HMs5JHxaTTsb5GUhYjiiTvNwU0MQavbwc4Dl29L0Xvw==} peerDependencies: @@ -2428,53 +3140,62 @@ packages: peerDependencies: '@solana/kit': ^2.1.0 + '@solana-program/token@0.6.0': + resolution: {integrity: sha512-omkZh4Tt9rre4wzWHNOhOEHyenXQku3xyc/UrKvShexA/Qlhza67q7uRwmwEDUs4QqoDBidSZPooOmepnA/jig==} + peerDependencies: + '@solana/kit': ^3.0 + '@solana/accounts@2.3.0': resolution: {integrity: sha512-QgQTj404Z6PXNOyzaOpSzjgMOuGwG8vC66jSDB+3zHaRcEPRVRd2sVSrd1U6sHtnV3aiaS6YyDuPQMheg4K2jw==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/accounts@3.0.3': + resolution: {integrity: sha512-KqlePrlZaHXfu8YQTCxN204ZuVm9o68CCcUr6l27MG2cuRUtEM1Ta0iR8JFkRUAEfZJC4Cu0ZDjK/v49loXjZQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/addresses@2.3.0': resolution: {integrity: sha512-ypTNkY2ZaRFpHLnHAgaW8a83N0/WoqdFvCqf4CQmnMdFsZSdC7qOwcbd7YzdaQn9dy+P2hybewzB+KP7LutxGA==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/addresses@3.0.3': + resolution: {integrity: sha512-AuMwKhJI89ANqiuJ/fawcwxNKkSeHH9CApZd2xelQQLS7X8uxAOovpcmEgiObQuiVP944s9ScGUT62Bdul9qYg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/assertions@2.3.0': resolution: {integrity: sha512-Ekoet3khNg3XFLN7MIz8W31wPQISpKUGDGTylLptI+JjCDWx3PIa88xjEMqFo02WJ8sBj2NLV64Xg1sBcsHjZQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' - '@solana/buffer-layout-utils@0.2.0': - resolution: {integrity: sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==} - engines: {node: '>= 10'} + '@solana/assertions@3.0.3': + resolution: {integrity: sha512-2qspxdbWp2y62dfCIlqeWQr4g+hE8FYSSwcaP6itwMwGRb8393yDGCJfI/znuzJh6m/XVWhMHIgFgsBwnevCmg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' '@solana/buffer-layout@4.0.1': resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} engines: {node: '>=5.10'} - '@solana/codecs-core@2.0.0-rc.1': - resolution: {integrity: sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==} - peerDependencies: - typescript: '>=5' - - '@solana/codecs-core@2.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'} peerDependencies: typescript: '>=5.3.3' - '@solana/codecs-data-structures@2.0.0-rc.1': - resolution: {integrity: sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==} + '@solana/codecs-core@3.0.3': + resolution: {integrity: sha512-emKykJ3h1DmnDOY29Uv9eJXP8E/FHzvlUBJ6te+5EbKdFjj7vdlKYPfDxOI6iGdXTY+YC/ELtbNBh6QwF2uEDQ==} + engines: {node: '>=20.18.0'} peerDependencies: - typescript: '>=5' + typescript: '>=5.3.3' '@solana/codecs-data-structures@2.3.0': resolution: {integrity: sha512-qvU5LE5DqEdYMYgELRHv+HMOx73sSoV1ZZkwIrclwUmwTbTaH8QAJURBj0RhQ/zCne7VuLLOZFFGv6jGigWhSw==} @@ -2482,13 +3203,8 @@ packages: peerDependencies: typescript: '>=5.3.3' - '@solana/codecs-numbers@2.0.0-rc.1': - resolution: {integrity: sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==} - peerDependencies: - typescript: '>=5' - - '@solana/codecs-numbers@2.1.1': - resolution: {integrity: sha512-m20IUPJhPUmPkHSlZ2iMAjJ7PaYUvlMtFhCQYzm9BEBSI6OCvXTG3GAPpAnSGRBfg5y+QNqqmKn4QHU3B6zzCQ==} + '@solana/codecs-data-structures@3.0.3': + resolution: {integrity: sha512-R15cLp8riJvToXziW8lP6AMSwsztGhEnwgyGmll32Mo0Yjq+hduW2/fJrA/TJs6tA/OgTzMQjlxgk009EqZHCw==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' @@ -2499,11 +3215,11 @@ packages: peerDependencies: typescript: '>=5.3.3' - '@solana/codecs-strings@2.0.0-rc.1': - resolution: {integrity: sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==} + '@solana/codecs-numbers@3.0.3': + resolution: {integrity: sha512-pfXkH9J0glrM8qj6389GAn30+cJOxzXLR2FsPOHCUMXrqLhGjMMZAWhsQkpOQ37SGc/7EiQsT/gmyGC7gxHqJQ==} + engines: {node: '>=20.18.0'} peerDependencies: - fastestsmallesttextencoderdecoder: ^1.0.22 - typescript: '>=5' + typescript: '>=5.3.3' '@solana/codecs-strings@2.3.0': resolution: {integrity: sha512-y5pSBYwzVziXu521hh+VxqUtp0hYGTl1eWGoc1W+8mdvBdC1kTqm/X7aYQw33J42hw03JjryvYOvmGgk3Qz/Ug==} @@ -2512,10 +3228,12 @@ packages: fastestsmallesttextencoderdecoder: ^1.0.22 typescript: '>=5.3.3' - '@solana/codecs@2.0.0-rc.1': - resolution: {integrity: sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==} + '@solana/codecs-strings@3.0.3': + resolution: {integrity: sha512-VHBXnnTVtcQ1j+7Vrz+qSYo38no+jiHRdGnhFspRXEHNJbllzwKqgBE7YN3qoIXH+MKxgJUcwO5KHmdzf8Wn2A==} + engines: {node: '>=20.18.0'} peerDependencies: - typescript: '>=5' + fastestsmallesttextencoderdecoder: ^1.0.22 + typescript: '>=5.3.3' '@solana/codecs@2.3.0': resolution: {integrity: sha512-JVqGPkzoeyU262hJGdH64kNLH0M+Oew2CIPOa/9tR3++q2pEd4jU2Rxdfye9sd0Ce3XJrR5AIa8ZfbyQXzjh+g==} @@ -2523,21 +3241,21 @@ packages: peerDependencies: typescript: '>=5.3.3' - '@solana/errors@2.0.0-rc.1': - resolution: {integrity: sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==} - hasBin: true + '@solana/codecs@3.0.3': + resolution: {integrity: sha512-GOHwTlIQsCoJx9Ryr6cEf0FHKAQ7pY4aO4xgncAftrv0lveTQ1rPP2inQ1QT0gJllsIa8nwbfXAADs9nNJxQDA==} + engines: {node: '>=20.18.0'} peerDependencies: - typescript: '>=5' + typescript: '>=5.3.3' - '@solana/errors@2.1.1': - resolution: {integrity: sha512-sj6DaWNbSJFvLzT8UZoabMefQUfSW/8tXK7NTiagsDmh+Q87eyQDDC9L3z+mNmx9b6dEf6z660MOIplDD2nfEw==} + '@solana/errors@2.3.0': + resolution: {integrity: sha512-66RI9MAbwYV0UtP7kGcTBVLxJgUxoZGm8Fbc0ah+lGiAw17Gugco6+9GrJCV83VyF2mDWyYnYM9qdI3yjgpnaQ==} engines: {node: '>=20.18.0'} hasBin: true peerDependencies: typescript: '>=5.3.3' - '@solana/errors@2.3.0': - resolution: {integrity: sha512-66RI9MAbwYV0UtP7kGcTBVLxJgUxoZGm8Fbc0ah+lGiAw17Gugco6+9GrJCV83VyF2mDWyYnYM9qdI3yjgpnaQ==} + '@solana/errors@3.0.3': + resolution: {integrity: sha512-1l84xJlHNva6io62PcYfUamwWlc0eM95nHgCrKX0g0cLoC6D6QHYPCEbEVkR+C5UtP9JDgyQM8MFiv+Ei5tO9Q==} engines: {node: '>=20.18.0'} hasBin: true peerDependencies: @@ -2549,40 +3267,77 @@ packages: peerDependencies: typescript: '>=5.3.3' + '@solana/fast-stable-stringify@3.0.3': + resolution: {integrity: sha512-ED0pxB6lSEYvg+vOd5hcuQrgzEDnOrURFgp1ZOY+lQhJkQU6xo+P829NcJZQVP1rdU2/YQPAKJKEseyfe9VMIw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/functional@2.3.0': resolution: {integrity: sha512-AgsPh3W3tE+nK3eEw/W9qiSfTGwLYEvl0rWaxHht/lRcuDVwfKRzeSa5G79eioWFFqr+pTtoCr3D3OLkwKz02Q==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/functional@3.0.3': + resolution: {integrity: sha512-2qX1kKANn8995vOOh5S9AmF4ItGZcfbny0w28Eqy8AFh+GMnSDN4gqpmV2LvxBI9HibXZptGH3RVOMk82h1Mpw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/instruction-plans@3.0.3': + resolution: {integrity: sha512-eqoaPtWtmLTTpdvbt4BZF5H6FIlJtXi9H7qLOM1dLYonkOX2Ncezx5NDCZ9tMb2qxVMF4IocYsQnNSnMfjQF1w==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/instructions@2.3.0': resolution: {integrity: sha512-PLMsmaIKu7hEAzyElrk2T7JJx4D+9eRwebhFZpy2PXziNSmFF929eRHKUsKqBFM3cYR1Yy3m6roBZfA+bGE/oQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/instructions@3.0.3': + resolution: {integrity: sha512-4csIi8YUDb5j/J+gDzmYtOvq7ZWLbCxj4t0xKn+fPrBk/FD2pK29KVT3Fu7j4Lh1/ojunQUP9X4NHwUexY3PnA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/keys@2.3.0': resolution: {integrity: sha512-ZVVdga79pNH+2pVcm6fr2sWz9HTwfopDVhYb0Lh3dh+WBmJjwkabXEIHey2rUES7NjFa/G7sV8lrUn/v8LDCCQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/keys@3.0.3': + resolution: {integrity: sha512-tp8oK9tMadtSIc4vF4aXXWkPd4oU5XPW8nf28NgrGDWGt25fUHIydKjkf2hPtMt9i1WfRyQZ33B5P3dnsNqcPQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/kit@2.3.0': resolution: {integrity: sha512-sb6PgwoW2LjE5oTFu4lhlS/cGt/NB3YrShEyx7JgWFWysfgLdJnhwWThgwy/4HjNsmtMrQGWVls0yVBHcMvlMQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/kit@3.0.3': + resolution: {integrity: sha512-CEEhCDmkvztd1zbgADsEQhmj9GyWOOGeW1hZD+gtwbBSF5YN1uofS/pex5MIh/VIqKRj+A2UnYWI1V+9+q/lyQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/nominal-types@2.3.0': resolution: {integrity: sha512-uKlMnlP4PWW5UTXlhKM8lcgIaNj8dvd8xO4Y9l+FVvh9RvW2TO0GwUO6JCo7JBzCB0PSqRJdWWaQ8pu1Ti/OkA==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' - '@solana/options@2.0.0-rc.1': - resolution: {integrity: sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==} + '@solana/nominal-types@3.0.3': + resolution: {integrity: sha512-aZavCiexeUAoMHRQg4s1AHkH3wscbOb70diyfjhwZVgFz1uUsFez7csPp9tNFkNolnadVb2gky7yBk3IImQJ6A==} + engines: {node: '>=20.18.0'} peerDependencies: - typescript: '>=5' + typescript: '>=5.3.3' '@solana/options@2.3.0': resolution: {integrity: sha512-PPnnZBRCWWoZQ11exPxf//DRzN2C6AoFsDI/u2AsQfYih434/7Kp4XLpfOMT/XESi+gdBMFNNfbES5zg3wAIkw==} @@ -2590,48 +3345,96 @@ packages: peerDependencies: typescript: '>=5.3.3' + '@solana/options@3.0.3': + resolution: {integrity: sha512-jarsmnQ63RN0JPC5j9sgUat07NrL9PC71XU7pUItd6LOHtu4+wJMio3l5mT0DHVfkfbFLL6iI6+QmXSVhTNF3g==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/programs@2.3.0': resolution: {integrity: sha512-UXKujV71VCI5uPs+cFdwxybtHZAIZyQkqDiDnmK+DawtOO9mBn4Nimdb/6RjR2CXT78mzO9ZCZ3qfyX+ydcB7w==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/programs@3.0.3': + resolution: {integrity: sha512-JZlVE3/AeSNDuH3aEzCZoDu8GTXkMpGXxf93zXLzbxfxhiQ/kHrReN4XE/JWZ/uGWbaFZGR5B3UtdN2QsoZL7w==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/promises@2.3.0': resolution: {integrity: sha512-GjVgutZKXVuojd9rWy1PuLnfcRfqsaCm7InCiZc8bqmJpoghlyluweNc7ml9Y5yQn1P2IOyzh9+p/77vIyNybQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/promises@3.0.3': + resolution: {integrity: sha512-K+UflGBVxj30XQMHTylHHZJdKH5QG3oj5k2s42GrZ/Wbu72oapVJySMBgpK45+p90t8/LEqV6rRPyTXlet9J+Q==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/rpc-api@2.3.0': resolution: {integrity: sha512-UUdiRfWoyYhJL9PPvFeJr4aJ554ob2jXcpn4vKmRVn9ire0sCbpQKYx6K8eEKHZWXKrDW8IDspgTl0gT/aJWVg==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/rpc-api@3.0.3': + resolution: {integrity: sha512-Yym9/Ama62OY69rAZgbOCAy1QlqaWAyb0VlqFuwSaZV1pkFCCFSwWEJEsiN1n8pb2ZP+RtwNvmYixvWizx9yvA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/rpc-parsed-types@2.3.0': resolution: {integrity: sha512-B5pHzyEIbBJf9KHej+zdr5ZNAdSvu7WLU2lOUPh81KHdHQs6dEb310LGxcpCc7HVE8IEdO20AbckewDiAN6OCg==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/rpc-parsed-types@3.0.3': + resolution: {integrity: sha512-/koM05IM2fU91kYDQxXil3VBNlOfcP+gXE0js1sdGz8KonGuLsF61CiKB5xt6u1KEXhRyDdXYLjf63JarL4Ozg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/rpc-spec-types@2.3.0': resolution: {integrity: sha512-xQsb65lahjr8Wc9dMtP7xa0ZmDS8dOE2ncYjlvfyw/h4mpdXTUdrSMi6RtFwX33/rGuztQ7Hwaid5xLNSLvsFQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/rpc-spec-types@3.0.3': + resolution: {integrity: sha512-A6Jt8SRRetnN3CeGAvGJxigA9zYRslGgWcSjueAZGvPX+MesFxEUjSWZCfl+FogVFvwkqfkgQZQbPAGZQFJQ6Q==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/rpc-spec@2.3.0': resolution: {integrity: sha512-fA2LMX4BMixCrNB2n6T83AvjZ3oUQTu7qyPLyt8gHQaoEAXs8k6GZmu6iYcr+FboQCjUmRPgMaABbcr9j2J9Sw==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/rpc-spec@3.0.3': + resolution: {integrity: sha512-MZn5/8BebB6MQ4Gstw6zyfWsFAZYAyLzMK+AUf/rSfT8tPmWiJ/mcxnxqOXvFup/l6D67U8pyGpIoFqwCeZqqA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/rpc-subscriptions-api@2.3.0': resolution: {integrity: sha512-9mCjVbum2Hg9KGX3LKsrI5Xs0KX390lS+Z8qB80bxhar6MJPugqIPH8uRgLhCW9GN3JprAfjRNl7our8CPvsPQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/rpc-subscriptions-api@3.0.3': + resolution: {integrity: sha512-MGgVK3PUS15qsjuhimpzGZrKD/CTTvS0mAlQ0Jw84zsr1RJVdQJK/F0igu07BVd172eTZL8d90NoAQ3dahW5pA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/rpc-subscriptions-channel-websocket@2.3.0': resolution: {integrity: sha512-2oL6ceFwejIgeWzbNiUHI2tZZnaOxNTSerszcin7wYQwijxtpVgUHiuItM/Y70DQmH9sKhmikQp+dqeGalaJxw==} engines: {node: '>=20.18.0'} @@ -2639,65 +3442,96 @@ packages: typescript: '>=5.3.3' ws: ^8.18.0 + '@solana/rpc-subscriptions-channel-websocket@3.0.3': + resolution: {integrity: sha512-zUzUlb8Cwnw+SHlsLrSqyBRtOJKGc+FvSNJo/vWAkLShoV0wUDMPv7VvhTngJx3B/3ANfrOZ4i08i9QfYPAvpQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + ws: ^8.18.0 + '@solana/rpc-subscriptions-spec@2.3.0': resolution: {integrity: sha512-rdmVcl4PvNKQeA2l8DorIeALCgJEMSu7U8AXJS1PICeb2lQuMeaR+6cs/iowjvIB0lMVjYN2sFf6Q3dJPu6wWg==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/rpc-subscriptions-spec@3.0.3': + resolution: {integrity: sha512-9KpQ32OBJWS85mn6q3gkM0AjQe1LKYlMU7gpJRrla/lvXxNLhI95tz5K6StctpUreVmRWTVkNamHE69uUQyY8A==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/rpc-subscriptions@2.3.0': resolution: {integrity: sha512-Uyr10nZKGVzvCOqwCZgwYrzuoDyUdwtgQRefh13pXIrdo4wYjVmoLykH49Omt6abwStB0a4UL5gX9V4mFdDJZg==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/rpc-subscriptions@3.0.3': + resolution: {integrity: sha512-LRvz6NaqvtsYFd32KwZ+rwYQ9XCs+DWjV8BvBLsJpt9/NWSuHf/7Sy/vvP6qtKxut692H/TMvHnC4iulg0WmiQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/rpc-transformers@2.3.0': resolution: {integrity: sha512-UuHYK3XEpo9nMXdjyGKkPCOr7WsZsxs7zLYDO1A5ELH3P3JoehvrDegYRAGzBS2VKsfApZ86ZpJToP0K3PhmMA==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/rpc-transformers@3.0.3': + resolution: {integrity: sha512-lzdaZM/dG3s19Tsk4mkJA5JBoS1eX9DnD7z62gkDwrwJDkDBzkAJT9aLcsYFfTmwTfIp6uU2UPgGYc97i1wezw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/rpc-transport-http@2.3.0': resolution: {integrity: sha512-HFKydmxGw8nAF5N+S0NLnPBDCe5oMDtI2RAmW8DMqP4U3Zxt2XWhvV1SNkAldT5tF0U1vP+is6fHxyhk4xqEvg==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/rpc-transport-http@3.0.3': + resolution: {integrity: sha512-bIXFwr2LR5A97Z46dI661MJPbHnPfcShBjFzOS/8Rnr8P4ho3j/9EUtjDrsqoxGJT3SLWj5OlyXAlaDAvVTOUQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/rpc-types@2.3.0': resolution: {integrity: sha512-O09YX2hED2QUyGxrMOxQ9GzH1LlEwwZWu69QbL4oYmIf6P5dzEEHcqRY6L1LsDVqc/dzAdEs/E1FaPrcIaIIPw==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' - '@solana/rpc@2.3.0': - resolution: {integrity: sha512-ZWN76iNQAOCpYC7yKfb3UNLIMZf603JckLKOOLTHuy9MZnTN8XV6uwvDFhf42XvhglgUjGCEnbUqWtxQ9pa/pQ==} + '@solana/rpc-types@3.0.3': + resolution: {integrity: sha512-petWQ5xSny9UfmC3Qp2owyhNU0w9SyBww4+v7tSVyXMcCC9v6j/XsqTeimH1S0qQUllnv0/FY83ohFaxofmZ6Q==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' - '@solana/signers@2.3.0': - resolution: {integrity: sha512-OSv6fGr/MFRx6J+ZChQMRqKNPGGmdjkqarKkRzkwmv7v8quWsIRnJT5EV8tBy3LI4DLO/A8vKiNSPzvm1TdaiQ==} + '@solana/rpc@2.3.0': + resolution: {integrity: sha512-ZWN76iNQAOCpYC7yKfb3UNLIMZf603JckLKOOLTHuy9MZnTN8XV6uwvDFhf42XvhglgUjGCEnbUqWtxQ9pa/pQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' - '@solana/spl-token-group@0.0.7': - resolution: {integrity: sha512-V1N/iX7Cr7H0uazWUT2uk27TMqlqedpXHRqqAbVO2gvmJyT0E0ummMEAVQeXZ05ZhQ/xF39DLSdBp90XebWEug==} - engines: {node: '>=16'} + '@solana/rpc@3.0.3': + resolution: {integrity: sha512-3oukAaLK78GegkKcm6iNmRnO4mFeNz+BMvA8T56oizoBNKiRVEq/6DFzVX/LkmZ+wvD601pAB3uCdrTPcC0YKQ==} + engines: {node: '>=20.18.0'} peerDependencies: - '@solana/web3.js': ^1.95.3 + typescript: '>=5.3.3' - '@solana/spl-token-metadata@0.1.6': - resolution: {integrity: sha512-7sMt1rsm/zQOQcUWllQX9mD2O6KhSAtY1hFR2hfFwgqfFWzSY9E9GDvFVNYUI1F0iQKcm6HmePU9QbKRXTEBiA==} - engines: {node: '>=16'} + '@solana/signers@2.3.0': + resolution: {integrity: sha512-OSv6fGr/MFRx6J+ZChQMRqKNPGGmdjkqarKkRzkwmv7v8quWsIRnJT5EV8tBy3LI4DLO/A8vKiNSPzvm1TdaiQ==} + engines: {node: '>=20.18.0'} peerDependencies: - '@solana/web3.js': ^1.95.3 + typescript: '>=5.3.3' - '@solana/spl-token@0.4.13': - resolution: {integrity: sha512-cite/pYWQZZVvLbg5lsodSovbetK/eA24gaR0eeUeMuBAMNrT8XFCwaygKy0N2WSg3gSyjjNpIeAGBAKZaY/1w==} - engines: {node: '>=16'} + '@solana/signers@3.0.3': + resolution: {integrity: sha512-UwCd/uPYTZiwd283JKVyOWLLN5sIgMBqGDyUmNU3vo9hcmXKv5ZGm/9TvwMY2z35sXWuIOcj7etxJ8OoWc/ObQ==} + engines: {node: '>=20.18.0'} peerDependencies: - '@solana/web3.js': ^1.95.5 + typescript: '>=5.3.3' '@solana/subscribable@2.3.0': resolution: {integrity: sha512-DkgohEDbMkdTWiKAoatY02Njr56WXx9e/dKKfmne8/Ad6/2llUIrax78nCdlvZW9quXMaXPTxZvdQqo9N669Og==} @@ -2705,32 +3539,62 @@ packages: peerDependencies: typescript: '>=5.3.3' + '@solana/subscribable@3.0.3': + resolution: {integrity: sha512-FJ27LKGHLQ5GGttPvTOLQDLrrOZEgvaJhB7yYaHAhPk25+p+erBaQpjePhfkMyUbL1FQbxn1SUJmS6jUuaPjlQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/sysvars@2.3.0': resolution: {integrity: sha512-LvjADZrpZ+CnhlHqfI5cmsRzX9Rpyb1Ox2dMHnbsRNzeKAMhu9w4ZBIaeTdO322zsTr509G1B+k2ABD3whvUBA==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/sysvars@3.0.3': + resolution: {integrity: sha512-GnHew+QeKCs2f9ow+20swEJMH4mDfJA/QhtPgOPTYQx/z69J4IieYJ7fZenSHnA//lJ45fVdNdmy1trypvPLBQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/transaction-confirmation@2.3.0': resolution: {integrity: sha512-UiEuiHCfAAZEKdfne/XljFNJbsKAe701UQHKXEInYzIgBjRbvaeYZlBmkkqtxwcasgBTOmEaEKT44J14N9VZDw==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/transaction-confirmation@3.0.3': + resolution: {integrity: sha512-dXx0OLtR95LMuARgi2dDQlL1QYmk56DOou5q9wKymmeV3JTvfDExeWXnOgjRBBq/dEfj4ugN1aZuTaS18UirFw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/transaction-messages@2.3.0': resolution: {integrity: sha512-bgqvWuy3MqKS5JdNLH649q+ngiyOu5rGS3DizSnWwYUd76RxZl1kN6CoqHSrrMzFMvis6sck/yPGG3wqrMlAww==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/transaction-messages@3.0.3': + resolution: {integrity: sha512-s+6NWRnBhnnjFWV4x2tzBzoWa6e5LiIxIvJlWwVQBFkc8fMGY04w7jkFh0PM08t/QFKeXBEWkyBDa/TFYdkWug==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/transactions@2.3.0': resolution: {integrity: sha512-LnTvdi8QnrQtuEZor5Msje61sDpPstTVwKg4y81tNxDhiyomjuvnSNLAq6QsB9gIxUqbNzPZgOG9IU4I4/Uaug==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' - '@solana/web3.js@1.98.2': - resolution: {integrity: sha512-BqVwEG+TaG2yCkBMbD3C4hdpustR4FpuUFRPUmqRZYYlPI9Hg4XMWxHWOWRzHE9Lkc9NDjzXFX7lDXSgzC7R1A==} + '@solana/transactions@3.0.3': + resolution: {integrity: sha512-iMX+n9j4ON7H1nKlWEbMqMOpKYC6yVGxKKmWHT1KdLRG7v+03I4DnDeFoI+Zmw56FA+7Bbne8jwwX60Q1vk/MQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/web3.js@1.98.4': + resolution: {integrity: sha512-vv9lfnvjUsRiq//+j5pBdXig0IQdtzA0BRZ3bXEP4KaIyF1CcaydWqgyzQgfZMNIsWNWmG+AUHwPy4AHOD6gpw==} '@svgr/babel-plugin-add-jsx-attribute@8.0.0': resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==} @@ -2810,20 +3674,17 @@ 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.81.5': - resolution: {integrity: sha512-ZJOgCy/z2qpZXWaj/oxvodDx07XcQa9BF92c0oINjHkoqUPsmm3uG08HpTaviviZ/N9eP1f9CM7mKSEkIo7O1Q==} + '@tanstack/query-core@5.90.5': + resolution: {integrity: sha512-wLamYp7FaDq6ZnNehypKI5fNvxHPfTYylE0m/ZpuuzJfJqhR5Pxg9gvGBHZx4n7J+V5Rg5mZxHHTlv25Zt5u+w==} - '@tanstack/react-query@5.81.5': - resolution: {integrity: sha512-lOf2KqRRiYWpQT86eeeftAGnjuTR35myTP8MXyvHa81VlomoAWNEd8x5vkcAfQefu0qtYCvyqLropFZqgI2EQw==} + '@tanstack/react-query@5.90.5': + resolution: {integrity: sha512-pN+8UWpxZkEJ/Rnnj2v2Sxpx1WFlaa9L6a4UO89p6tTQbeo+m0MS8oYDjbggrR8QcTyjKoYWKS3xJQGr3ExT8Q==} peerDependencies: react: ^18 || ^19 @@ -2831,26 +3692,14 @@ packages: resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} - '@tsconfig/node10@1.0.11': - resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} - - '@tsconfig/node12@1.0.11': - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - - '@tsconfig/node14@1.0.3': - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - - '@tsconfig/node16@1.0.4': - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - - '@tybys/wasm-util@0.9.0': - resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} '@types/body-parser@1.19.6': resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} - '@types/chai@5.2.2': - resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} @@ -2867,8 +3716,8 @@ packages: '@types/express-serve-static-core@4.19.6': resolution: {integrity: sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==} - '@types/express-serve-static-core@5.0.6': - resolution: {integrity: sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==} + '@types/express-serve-static-core@5.1.0': + resolution: {integrity: sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA==} '@types/express@4.17.23': resolution: {integrity: sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==} @@ -2885,6 +3734,9 @@ 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==} @@ -2906,13 +3758,13 @@ packages: '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - '@types/react-dom@19.1.6': - resolution: {integrity: sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==} + '@types/react-dom@19.2.2': + resolution: {integrity: sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==} peerDependencies: - '@types/react': ^19.0.0 + '@types/react': ^19.2.0 - '@types/react@19.1.8': - resolution: {integrity: sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==} + '@types/react@19.2.2': + resolution: {integrity: sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==} '@types/send@0.17.5': resolution: {integrity: sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==} @@ -2932,157 +3784,157 @@ packages: '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} - '@typescript-eslint/eslint-plugin@8.35.1': - resolution: {integrity: sha512-9XNTlo7P7RJxbVeICaIIIEipqxLKguyh+3UbXuT2XQuFp6d8VOeDEGuz5IiX0dgZo8CiI6aOFLg4e8cF71SFVg==} + '@typescript-eslint/eslint-plugin@8.46.2': + resolution: {integrity: sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.35.1 + '@typescript-eslint/parser': ^8.46.2 eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.35.1': - resolution: {integrity: sha512-3MyiDfrfLeK06bi/g9DqJxP5pV74LNv4rFTyvGDmT3x2p1yp1lOd+qYZfiRPIOf/oON+WRZR5wxxuF85qOar+w==} + '@typescript-eslint/parser@8.46.2': + resolution: {integrity: sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.35.1': - resolution: {integrity: sha512-VYxn/5LOpVxADAuP3NrnxxHYfzVtQzLKeldIhDhzC8UHaiQvYlXvKuVho1qLduFbJjjy5U5bkGwa3rUGUb1Q6Q==} + '@typescript-eslint/project-service@8.46.2': + resolution: {integrity: sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.35.1': - resolution: {integrity: sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg==} + '@typescript-eslint/scope-manager@8.46.2': + resolution: {integrity: sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.35.1': - resolution: {integrity: sha512-K5/U9VmT9dTHoNowWZpz+/TObS3xqC5h0xAIjXPw+MNcKV9qg6eSatEnmeAwkjHijhACH0/N7bkhKvbt1+DXWQ==} + '@typescript-eslint/tsconfig-utils@8.46.2': + resolution: {integrity: sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.35.1': - resolution: {integrity: sha512-HOrUBlfVRz5W2LIKpXzZoy6VTZzMu2n8q9C2V/cFngIC5U1nStJgv0tMV4sZPzdf4wQm9/ToWUFPMN9Vq9VJQQ==} + '@typescript-eslint/type-utils@8.46.2': + resolution: {integrity: sha512-HbPM4LbaAAt/DjxXaG9yiS9brOOz6fabal4uvUmaUYe6l3K1phQDMQKBRUrr06BQkxkvIZVVHttqiybM9nJsLA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.35.1': - resolution: {integrity: sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==} + '@typescript-eslint/types@8.46.2': + resolution: {integrity: sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.35.1': - resolution: {integrity: sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g==} + '@typescript-eslint/typescript-estree@8.46.2': + resolution: {integrity: sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.35.1': - resolution: {integrity: sha512-lhnwatFmOFcazAsUm3ZnZFpXSxiwoa1Lj50HphnDe1Et01NF4+hrdXONSUHIcbVu2eFb1bAf+5yjXkGVkXBKAQ==} + '@typescript-eslint/utils@8.46.2': + resolution: {integrity: sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.35.1': - resolution: {integrity: sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw==} + '@typescript-eslint/visitor-keys@8.46.2': + resolution: {integrity: sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@unrs/resolver-binding-android-arm-eabi@1.10.1': - resolution: {integrity: sha512-zohDKXT1Ok0yhbVGff4YAg9HUs5ietG5GpvJBPFSApZnGe7uf2cd26DRhKZbn0Be6xHUZrSzP+RAgMmzyc71EA==} + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} cpu: [arm] os: [android] - '@unrs/resolver-binding-android-arm64@1.10.1': - resolution: {integrity: sha512-tAN6k5UrTd4nicpA7s2PbjR/jagpDzAmvXFjbpTazUe5FRsFxVcBlS1F5Lzp5jtWU6bdiqRhSvd4X8rdpCffeA==} + '@unrs/resolver-binding-android-arm64@1.11.1': + resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} cpu: [arm64] os: [android] - '@unrs/resolver-binding-darwin-arm64@1.10.1': - resolution: {integrity: sha512-+FCsag8WkauI4dQ50XumCXdfvDCZEpMUnvZDsKMxfOisnEklpDFXc6ThY0WqybBYZbiwR5tWcFaZmI0G6b4vrg==} + '@unrs/resolver-binding-darwin-arm64@1.11.1': + resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} cpu: [arm64] os: [darwin] - '@unrs/resolver-binding-darwin-x64@1.10.1': - resolution: {integrity: sha512-qYKGGm5wk71ONcXTMZ0+J11qQeOAPz3nw6VtqrBUUELRyXFyvK8cHhHsLBFR4GHnilc2pgY1HTB2TvdW9wO26Q==} + '@unrs/resolver-binding-darwin-x64@1.11.1': + resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} cpu: [x64] os: [darwin] - '@unrs/resolver-binding-freebsd-x64@1.10.1': - resolution: {integrity: sha512-hOHMAhbvIQ63gkpgeNsXcWPSyvXH7ZEyeg254hY0Lp/hX8NdW+FsUWq73g9946Pc/BrcVI/I3C1cmZ4RCX9bNw==} + '@unrs/resolver-binding-freebsd-x64@1.11.1': + resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} cpu: [x64] os: [freebsd] - '@unrs/resolver-binding-linux-arm-gnueabihf@1.10.1': - resolution: {integrity: sha512-6ds7+zzHJgTDmpe0gmFcOTvSUhG5oZukkt+cCsSb3k4Uiz2yEQB4iCRITX2hBwSW+p8gAieAfecITjgqCkswXw==} + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} cpu: [arm] os: [linux] - '@unrs/resolver-binding-linux-arm-musleabihf@1.10.1': - resolution: {integrity: sha512-P7A0G2/jW00diNJyFeq4W9/nxovD62Ay8CMP4UK9OymC7qO7rG1a8Upad68/bdfpIOn7KSp7Aj/6lEW3yyznAA==} + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} cpu: [arm] os: [linux] - '@unrs/resolver-binding-linux-arm64-gnu@1.10.1': - resolution: {integrity: sha512-Cg6xzdkrpltcTPO4At+A79zkC7gPDQIgosJmVV8M104ImB6KZi1MrNXgDYIAfkhUYjPzjNooEDFRAwwPadS7ZA==} + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} cpu: [arm64] os: [linux] - '@unrs/resolver-binding-linux-arm64-musl@1.10.1': - resolution: {integrity: sha512-aNeg99bVkXa4lt+oZbjNRPC8ZpjJTKxijg/wILrJdzNyAymO2UC/HUK1UfDjt6T7U5p/mK24T3CYOi3/+YEQSA==} + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} cpu: [arm64] os: [linux] - '@unrs/resolver-binding-linux-ppc64-gnu@1.10.1': - resolution: {integrity: sha512-ylz5ojeXrkPrtnzVhpCO+YegG63/aKhkoTlY8PfMfBfLaUG8v6m6iqrL7sBUKdVBgOB4kSTUPt9efQdA/Y3Z/w==} + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} cpu: [ppc64] os: [linux] - '@unrs/resolver-binding-linux-riscv64-gnu@1.10.1': - resolution: {integrity: sha512-xcWyhmJfXXOxK7lvE4+rLwBq+on83svlc0AIypfe6x4sMJR+S4oD7n9OynaQShfj2SufPw2KJAotnsNb+4nN2g==} + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} cpu: [riscv64] os: [linux] - '@unrs/resolver-binding-linux-riscv64-musl@1.10.1': - resolution: {integrity: sha512-mW9JZAdOCyorgi1eLJr4gX7xS67WNG9XNPYj5P8VuttK72XNsmdw9yhOO4tDANMgiLXFiSFaiL1gEpoNtRPw/A==} + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} cpu: [riscv64] os: [linux] - '@unrs/resolver-binding-linux-s390x-gnu@1.10.1': - resolution: {integrity: sha512-NZGKhBy6xkJ0k09cWNZz4DnhBcGlhDd3W+j7EYoNvf5TSwj2K6kbmfqTWITEgkvjsMUjm1wsrc4IJaH6VtjyHQ==} + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} cpu: [s390x] os: [linux] - '@unrs/resolver-binding-linux-x64-gnu@1.10.1': - resolution: {integrity: sha512-VsjgckJ0gNMw7p0d8In6uPYr+s0p16yrT2rvG4v2jUpEMYkpnfnCiALa9SWshbvlGjKQ98Q2x19agm3iFk8w8Q==} + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} cpu: [x64] os: [linux] - '@unrs/resolver-binding-linux-x64-musl@1.10.1': - resolution: {integrity: sha512-idMnajMeejnaFi0Mx9UTLSYFDAOTfAEP7VjXNgxKApso3Eu2Njs0p2V95nNIyFi4oQVGFmIuCkoznAXtF/Zbmw==} + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} cpu: [x64] os: [linux] - '@unrs/resolver-binding-wasm32-wasi@1.10.1': - resolution: {integrity: sha512-7jyhjIRNFjzlr8x5pth6Oi9hv3a7ubcVYm2GBFinkBQKcFhw4nIs5BtauSNtDW1dPIGrxF0ciynCZqzxMrYMsg==} + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@unrs/resolver-binding-win32-arm64-msvc@1.10.1': - resolution: {integrity: sha512-TY79+N+Gkoo7E99K+zmsKNeiuNJYlclZJtKqsHSls8We2iGhgxtletVsiBYie93MSTDRDMI8pkBZJlIJSZPrdA==} + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} cpu: [arm64] os: [win32] - '@unrs/resolver-binding-win32-ia32-msvc@1.10.1': - resolution: {integrity: sha512-BAJN5PEPlEV+1m8+PCtFoKm3LQ1P57B4Z+0+efU0NzmCaGk7pUaOxuPgl+m3eufVeeNBKiPDltG0sSB9qEfCxw==} + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} cpu: [ia32] os: [win32] - '@unrs/resolver-binding-win32-x64-msvc@1.10.1': - resolution: {integrity: sha512-2v3erKKmmCyIVvvhI2nF15qEbdBpISTq44m9pyd5gfIJB1PN94oePTLWEd82XUbIbvKhv76xTSeUQSCOGesLeg==} + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} cpu: [x64] os: [win32] @@ -3115,18 +3967,28 @@ packages: '@vitest/utils@3.2.4': resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} - '@wagmi/connectors@5.8.5': - resolution: {integrity: sha512-CHh4uYP6MziCMlSVXmuAv7wMoYWdxXliuzwCRAxHNNkgXE7z37ez5XzJu0Sm39NUau3Fl8WSjwKo4a4w9BOYNA==} + '@wagmi/connectors@5.11.2': + resolution: {integrity: sha512-OkiElOI8xXGPDZE5UdG6NgDT3laSkEh9llX1DDapUnfnKecK3Tr/HUf5YzgwDhEoox8mdxp+8ZCjtnTKz56SdA==} + peerDependencies: + '@wagmi/core': 2.21.2 + typescript: '>=5.0.4' + viem: 2.x + peerDependenciesMeta: + typescript: + optional: true + + '@wagmi/connectors@6.1.0': + resolution: {integrity: sha512-MnpJHEABUIsajNxLc6br0LiqJvoFZbavQ6yG+mQb7Xlb3Hmm3IRjH5NU1g2zw5PCTRd3BFQLjwniLdwDnUPYNw==} peerDependencies: - '@wagmi/core': 2.17.3 + '@wagmi/core': 2.22.1 typescript: '>=5.0.4' viem: 2.x peerDependenciesMeta: typescript: optional: true - '@wagmi/core@2.17.3': - resolution: {integrity: sha512-fgZR9fAiCFtGaosTspkTx5lidccq9Z5xRWOk1HG0VfB6euQGw2//Db7upiP4uQ7DPst2YS9yQN2A1m9+iJLYCw==} + '@wagmi/core@2.22.1': + resolution: {integrity: sha512-cG/xwQWsBEcKgRTkQVhH29cbpbs/TdcUJVFXCyri3ZknxhMyGv0YEjTcrNpRgt2SaswL1KrvslSNYKKo+5YEAg==} peerDependencies: '@tanstack/query-core': '>=5.0.0' typescript: '>=5.0.4' @@ -3247,6 +4109,28 @@ 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==} + 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'} @@ -3256,17 +4140,13 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn-walk@8.3.4: - resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} - engines: {node: '>=0.4.0'} - acorn@8.15.0: resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} engines: {node: '>=0.4.0'} hasBin: true - agent-base@7.1.3: - resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} agentkeepalive@4.6.0: @@ -3276,20 +4156,23 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.1.0: - resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} engines: {node: '>=12'} ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - 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: @@ -3303,9 +4186,6 @@ packages: resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==} engines: {node: '>=14'} - arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} @@ -3383,8 +4263,8 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axe-core@4.10.3: - resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==} + axe-core@4.11.0: + resolution: {integrity: sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ==} engines: {node: '>=4'} axios-retry@4.5.0: @@ -3395,6 +4275,9 @@ packages: 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'} @@ -3426,23 +4309,17 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + baseline-browser-mapping@2.8.19: + resolution: {integrity: sha512-zoKGUdu6vb2jd3YOq0nnhEDQVbPcHhco3UImJrv5dSkvxTc2pl2WjOPsjZXDwPDSl5eghIMuY3R6J9NDKF3KcQ==} + hasBin: true + big.js@6.2.2: resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} - bigint-buffer@1.1.5: - resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} - engines: {node: '>= 10.0.0'} - - bignumber.js@9.3.0: - resolution: {integrity: sha512-EM7aMFTXbptt/wZdMlBv2t8IViwQL+h6SLHosp8Yf0dqJMTnY6iL32opnAB6kAdL0SZPuvcAzFr31o0c/R3/RA==} - binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} - bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - bn.js@4.12.2: resolution: {integrity: sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==} @@ -3459,8 +4336,8 @@ packages: borsh@0.7.0: resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} - bowser@2.11.0: - resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} + bowser@2.12.1: + resolution: {integrity: sha512-z4rE2Gxh7tvshQ4hluIT7XcFrgLIQaw9X3A+kTTRdovCz5PMukm/0QC/BKSYPj3omF5Qfypn9O/c5kgpmvYUCw==} brace-expansion@1.1.12: resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} @@ -3488,12 +4365,12 @@ packages: resolution: {integrity: sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==} engines: {node: '>= 0.10'} - browserify-sign@4.2.3: - resolution: {integrity: sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==} - engines: {node: '>= 0.12'} + browserify-sign@4.2.5: + resolution: {integrity: sha512-C2AUdAJg6rlM2W5QMp2Q4KGQMVBwR1lIimTsUnutJ8bMpW5B52pGpR2gEnNBNwijumDo5FojQ0L9JrXA8m4YEw==} + engines: {node: '>= 0.10'} - browserslist@4.25.1: - resolution: {integrity: sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==} + browserslist@4.27.0: + resolution: {integrity: sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -3525,10 +4402,6 @@ 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'} @@ -3565,19 +4438,19 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001726: - resolution: {integrity: sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==} + caniuse-lite@1.0.30001751: + resolution: {integrity: sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==} - chai@5.2.0: - resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} - engines: {node: '>=12'} + 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.4.1: - resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} + 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: @@ -3595,8 +4468,8 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} - 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'} client-only@0.0.1: @@ -3620,13 +4493,6 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - color-string@1.9.1: - resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} - - color@4.2.3: - resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} - engines: {node: '>=12.5.0'} - combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} @@ -3634,13 +4500,9 @@ packages: comlink@4.4.2: resolution: {integrity: sha512-OxGdvBmJuNKSCMO4NTl1L47VRp6xn2wG4F/2hYzB6tiCb709otOxtEYCSvK80PtjODfXXZu8ds+Nw5kVCjqd2g==} - commander@12.1.0: - resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} - engines: {node: '>=18'} - - commander@13.1.0: - resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} - engines: {node: '>=18'} + commander@14.0.0: + resolution: {integrity: sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==} + engines: {node: '>=20'} commander@14.0.1: resolution: {integrity: sha512-2JkV3gUZUVrbNA+1sjBOYLsMZ5cEEl8GTFP2a4AVz5hvasAMCQ1D2l2le/cX+pV4N6ZU17zjUahLpIXRrnWL8A==} @@ -3692,8 +4554,8 @@ packages: resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} engines: {node: '>= 0.6'} - core-js-compat@3.43.0: - resolution: {integrity: sha512-2GML2ZsCc5LR7hZYz4AXmjQw8zuy2T//2QntwdnpuYI7jteT6GVYJL7F6C2C57R7gSYrcqVW3lAALefdbhBLDA==} + core-js-compat@3.46.0: + resolution: {integrity: sha512-p9hObIIEENxSV8xIu+V68JjSeARg6UVMG5mR+JEUguG3sI6MsiS1njz2jHmyJDvA+8jX/sytkBHup6kxhM9law==} core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -3715,18 +4577,12 @@ packages: create-ecdh@4.0.4: resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==} - create-hash@1.1.3: - resolution: {integrity: sha512-snRpch/kwQhcdlnZKYanNF1m0RDlrCdSKQaH87w1FCFPVPNCQ/Il9QJKAX2jVBZddRdaHBMC+zXa9Gw9tmkNUA==} - create-hash@1.2.0: resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} create-hmac@1.1.7: resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} - create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - cross-fetch@3.2.0: resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} @@ -3820,8 +4676,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: '*' @@ -3829,8 +4685,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: '*' @@ -3842,8 +4698,8 @@ packages: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} - decimal.js@10.5.0: - resolution: {integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==} + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} decode-uri-component@0.2.2: resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} @@ -3901,17 +4757,13 @@ 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.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} - diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} - diffie-hellman@5.0.3: resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==} @@ -3963,15 +4815,15 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - eciesjs@0.4.15: - resolution: {integrity: sha512-r6kEJXDKecVOCj2nLMuXK/FCPeurW33+3JRpfXVbjLja3XUYFfD9I/JBreH6sUyzcm3G/YQboBjMla6poKeSdA==} + eciesjs@0.4.16: + resolution: {integrity: sha512-dS5cbA9rA2VR4Ybuvhg6jvdmp46ubLn3E+px8cG/35aEDNclrqoCjg6mt0HYZ/M+OoESS3jSkCrqk1kWAEhWAw==} engines: {bun: '>=1', deno: '>=2', node: '>=16'} ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.5.179: - resolution: {integrity: sha512-UWKi/EbBopgfFsc5k61wFpV7WrnnSlSzW/e2XcBmS6qKYTivZlLtoll5/rdqRTxGglGHkmkW0j0pFNJG10EUIQ==} + electron-to-chromium@1.5.239: + resolution: {integrity: sha512-1y5w0Zsq39MSPmEjHjbizvhYoTaulVtivpxkp5q5kaPmQtsK6/2nvAzGRxNMS9DoYySp9PkW0MAQDwU1m764mg==} elliptic@6.6.1: resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==} @@ -4011,8 +4863,8 @@ packages: resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} - 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==} @@ -4147,8 +4999,8 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 - eslint-plugin-prettier@5.5.1: - resolution: {integrity: sha512-dobTkHT6XaEVOo8IO90Q4DOSxnm3Y151QxPJlM/vKC0bVy+d6cVWQZLlFiuZPP0wS6vZwSKeJgKkcS+KfMBlRw==} + eslint-plugin-prettier@5.5.4: + resolution: {integrity: sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: '@types/eslint': '>=8.0.0' @@ -4185,8 +5037,8 @@ packages: resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.30.1: - resolution: {integrity: sha512-zmxXPNMOXmwm9E0yQLi5uqXHs7uq2UIiqEKo3Gq+3fwo1XrJ+hijAZImyF7hclW3E6oHz43Yk3RP8at6OTKflQ==} + eslint@9.38.0: + resolution: {integrity: sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -4256,8 +5108,8 @@ packages: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} - expect-type@1.2.1: - resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==} + expect-type@1.2.2: + resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} engines: {node: '>=12.0.0'} express@4.21.2: @@ -4302,14 +5154,18 @@ 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==} + fastestsmallesttextencoderdecoder@1.0.22: resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==} fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} - fdir@6.4.6: - resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -4320,9 +5176,6 @@ packages: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} - file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -4374,6 +5227,10 @@ packages: 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'} + forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -4397,6 +5254,10 @@ packages: functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -4467,8 +5328,8 @@ packages: resolution: {integrity: sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} - h3@1.15.3: - resolution: {integrity: sha512-z6GknHqyX0h9aQaTx22VZDf6QyZn+0Nh+Ym8O/u0SGSkyF5cuTJYKlc8MkzW3Nzf9LE1ivcpmYC3FUGpywhuUQ==} + h3@1.15.4: + resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==} has-bigints@1.1.0: resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} @@ -4493,13 +5354,14 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} - hash-base@2.0.2: - resolution: {integrity: sha512-0TROgQ1/SxE6KmxWSvXHvRj90/Xo1JvZShofnYF+f6ZsGtR4eES7WfrQzPalmyagfKZCXpVnitiRebZulWsbiw==} - hash-base@3.0.5: resolution: {integrity: sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==} engines: {node: '>= 0.10'} + 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==} @@ -4510,8 +5372,8 @@ packages: hmac-drbg@1.0.1: resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} - hono@4.8.3: - resolution: {integrity: sha512-jYZ6ZtfWjzBdh8H/0CIFfCBHaFL75k+KMzaM177hrWWm2TWL39YMYaJgB74uK/niRc866NMlH9B8uCvIo284WQ==} + hono@4.10.2: + resolution: {integrity: sha512-p6fyzl+mQo6uhESLxbF5WlBOAJMDh36PljwlKtP5V1v09NxlqGru3ShK+4wKhSuhuYf8qxMmrivHOa/M7q0sMg==} engines: {node: '>=16.9.0'} html-encoding-sniffer@4.0.0: @@ -4545,6 +5407,9 @@ 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==} @@ -4592,9 +5457,6 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - 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==} engines: {node: '>= 0.4'} @@ -4645,8 +5507,8 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - is-generator-function@1.1.0: - resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} engines: {node: '>= 0.4'} is-glob@4.0.3: @@ -4759,8 +5621,8 @@ packages: jose@5.10.0: resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} - jose@6.0.11: - resolution: {integrity: sha512-QxG7EaliDARm1O1S8BGakqncGT9s25bKL1WSf6/oa17Tkqwi8D2ZNglqCF+DsYF88/rV66Q/Q2mFAy697E1DUg==} + jose@6.1.0: + resolution: {integrity: sha512-TTQJyoEoKcC1lscpVDCSsVgYzUDg/0Bt3WE//WiTPK6uOCQC2KZS4MpugbMWt/zyjkopgZoXhZuCi00gLudfUA==} joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} @@ -4789,11 +5651,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'} @@ -4815,6 +5672,9 @@ packages: json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -4862,11 +5722,11 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - lit-element@4.2.0: - resolution: {integrity: sha512-MGrXJVAI5x+Bfth/pU9Kst1iWID6GHDLEzFEnyULB/sFiRLgkd8NPK/PeeXxktA3T6EIIaq8U3KcbTU5XFcP2Q==} + lit-element@4.2.1: + resolution: {integrity: sha512-WGAWRGzirAgyphK2urmYOV72tlvnxw7YfyLDgQ+OZnM9vQQBQnumQ7jUJe6unEzwGU3ahFOjuz1iz1jjrpCPuw==} - lit-html@3.3.0: - resolution: {integrity: sha512-RHoswrFAxY2d8Cf2mm4OZ1DgzCoBKUKSPvA1fhtSELxUERq2aQQ2h05pO9j81gS1o7RIRJ+CePLogfyahwmynw==} + lit-html@3.3.1: + resolution: {integrity: sha512-S9hbyDu/vs1qNrithiNyeyv64c9yqiW9l+DBgI18fL+MTvOtWoFR0FWiyq1TxaYef5wNlpEmzlXoBlZEO+WjoA==} lit@3.3.0: resolution: {integrity: sha512-DGVsqsOIHBww2DqnuZzW7QsuCdahp50ojuDaBPC7jUDRpYoH0z7kHBBYZewRzer75FwtrkmkKk7iOAwSaWdBmw==} @@ -4899,8 +5759,8 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true - loupe@3.1.4: - resolution: {integrity: sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==} + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} @@ -4911,11 +5771,8 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - magic-string@0.30.17: - resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} - - make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + magic-string@0.30.19: + resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} @@ -5007,12 +5864,15 @@ packages: typescript: optional: 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==} @@ -5027,8 +5887,8 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - napi-postinstall@0.3.0: - resolution: {integrity: sha512-M7NqKyhODKV1gRLdkwE7pDsZP2/SC2a2vHkOYh9MCpKMbWVfyVfUw5MaH83Fv6XMjxr5jryUp3IDDL9rlxsTeA==} + napi-postinstall@0.3.4: + resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} hasBin: true @@ -5039,29 +5899,8 @@ packages: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} - 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.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 - sass: ^1.3.0 - peerDependenciesMeta: - '@opentelemetry/api': - optional: true - '@playwright/test': - optional: true - babel-plugin-react-compiler: - optional: true - sass: - optional: true - - next@15.4.0-canary.113: - resolution: {integrity: sha512-OfYlHgR8UOAu9m3zS74fM9yPCRHuRE8q2en7votw84FLm7AWP2FtepznMj+t+65cd4IUdyXefkJvGsHcDmXC2Q==} + next@15.5.6: + resolution: {integrity: sha512-zTxsnI3LQo3c9HSdSf91O1jMNsEzIXDShXd4wVdg9y5shwLqBXi4ZtUUJyB86KGVSJLZx0PFONvO54aheGX8QQ==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} hasBin: true peerDependencies: @@ -5087,8 +5926,8 @@ packages: node-addon-api@2.0.2: resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==} - node-fetch-native@1.6.6: - resolution: {integrity: sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==} + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} @@ -5103,11 +5942,11 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-mock-http@1.0.1: - resolution: {integrity: sha512-0gJJgENizp4ghds/Ywu2FCmcRsgBTmRQzYPZm61wy+Em2sBarSka0OhQS5huLBg6od1zkNpnWMCZloQDFVvOMQ==} + 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.26: + resolution: {integrity: sha512-S2M9YimhSjBSvYnlr5/+umAnPHE++ODwt5e2Ij6FoX45HA/s4vHdkDx1eax2pAPeAOqu4s9b7ppahsyEFdVqQA==} normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} @@ -5120,8 +5959,8 @@ packages: nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - nwsapi@2.2.20: - resolution: {integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==} + nwsapi@2.2.22: + resolution: {integrity: sha512-ujSMe1OWVn55euT1ihwCI1ZcAaAU3nxUiDwfDQldc51ZXaB9m2AyOn6/jh1BLe2t/G8xd6uKG1UBF2aZJeg2SQ==} obj-multiplex@1.0.0: resolution: {integrity: sha512-0GNJAOsHoBHeNTvl5Vt6IWnpUEcc3uSRxzBri7EDyIcMgYvnY2JL2qdeV5zTMjWQX5OHcD5amcW2HFfDh0gjIA==} @@ -5179,6 +6018,12 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} + openapi-fetch@0.13.8: + resolution: {integrity: sha512-yJ4QKRyNxE44baQ9mY5+r/kAzZ8yXMemtNAOFwOzRXJscdjSxxzWSNlyBAr+o5JjkUw9Lc3W7OIoca0cY3PYnQ==} + + openapi-typescript-helpers@0.0.15: + resolution: {integrity: sha512-opyTPaunsklCBpTK8JGef6mfPhLSnyy5a0IN9vKtx3+4aExf+KxEqYwIy3hqkedXIB97u357uLMJsOnm3GVjsw==} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -5203,6 +6048,14 @@ 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.8.1: resolution: {integrity: sha512-e+z5epnzV+Zuz91YYujecW8cF01mzmrUtWotJ0oEPym/G82uccs7q0WDHTYL3eiONbTUEvcZrptAKLgTBD3u2A==} peerDependencies: @@ -5211,6 +6064,22 @@ packages: typescript: optional: true + ox@0.9.12: + resolution: {integrity: sha512-esyA5WXfFhlxpgzoVIEreRaasqqv95sjFpk3L4Me4RWk8bgBDe+J4wO3RZ5ikYmJ2Bbjyv+jKgxyaOzX6JpHPA==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + ox@0.9.6: + resolution: {integrity: sha512-8SuCbHPvv2eZLYXrNmC0EC12rdzXQLdhnOMlHDW2wiCPLxBrOOJwX5L5E61by+UjTPOryqQiRSnjIKCI+GykKg==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} @@ -5238,8 +6107,8 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} - parse-asn1@5.1.7: - resolution: {integrity: sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==} + parse-asn1@5.1.9: + resolution: {integrity: sha512-fIYNuZ/HastSb80baGOuPRo1O9cf4baWw5WsAp7dBuUzeTD/BoaG8sVTdlPFksBE2lF21dN+A1AnrpIjSWqHHg==} engines: {node: '>= 0.10'} parse-imports-exports@0.2.4: @@ -5288,9 +6157,9 @@ packages: resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} engines: {node: '>= 14.16'} - pbkdf2@3.1.3: - resolution: {integrity: sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA==} - engines: {node: '>=0.12'} + pbkdf2@3.1.5: + resolution: {integrity: sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==} + engines: {node: '>= 0.10'} picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -5299,8 +6168,8 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - picomatch@4.0.2: - resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} pify@2.3.0: @@ -5340,6 +6209,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'} @@ -5350,8 +6239,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 @@ -5407,8 +6296,11 @@ packages: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} - preact@10.26.9: - resolution: {integrity: sha512-SSjF9vcnF27mJK1XyFMNJzFd5u3pQiATFqoaDy03XuN00u4ziveVVEGt5RKJrDR8MHE/wJo9Nnad56RLzS2RMA==} + preact@10.24.2: + resolution: {integrity: sha512-1cSoF0aCC8uaARATfrlz4VCBqE8LwZwRfLgkxJOQwAlQt6ayTmi0D9OF7nXid1POI5SZidFuG9CnlXbDfLqY/Q==} + + preact@10.27.2: + resolution: {integrity: sha512-5SYSgFKSyhCbk6SrXyMpqjb5+MQBgfvEKE/OC+PujcY34sOpqtr+0AZQtPYx5IA6VxynQ7rUPCtKzyovpj9Bpg==} prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} @@ -5493,16 +6385,16 @@ packages: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} - react-dom@19.1.0: - resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==} + react-dom@19.2.0: + resolution: {integrity: sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==} peerDependencies: - react: ^19.1.0 + react: ^19.2.0 react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - react@19.1.0: - resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} + react@19.2.0: + resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==} engines: {node: '>=0.10.0'} read-cache@1.0.0: @@ -5531,8 +6423,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: @@ -5542,21 +6434,25 @@ 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 require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + require-main-filename@2.0.0: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} @@ -5571,8 +6467,8 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - resolve@1.22.10: - resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} engines: {node: '>= 0.4'} hasBin: true @@ -5584,19 +6480,17 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - ripemd160@2.0.1: - resolution: {integrity: sha512-J7f4wutN8mdbV08MJnXibYpCOPHR+yzy+iQ/AsjMv2j8cLavQ8VGagDFUwwTAdF8FmRKVeNpbTTEwNHCW1g94w==} - - 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'} - rollup@4.44.1: - resolution: {integrity: sha512-x8H8aPvD+xbl0Do8oez5f5o8eMS3trfCghc4HhLAnCkj7Vl0d1JWGs0UF/D886zLW2rOj2QymV/JcSSsw+XDNg==} + rollup@4.52.5: + resolution: {integrity: sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - rpc-websockets@9.1.1: - resolution: {integrity: sha512-1IXGM/TfPT6nfYMIXkJdzn+L4JEsmb0FL1O2OBjaH03V3yuUDdKFulGLMFG6ErV+8pZ5HVC0limve01RyO+saA==} + rpc-websockets@9.2.0: + resolution: {integrity: sha512-DS/XHdPxplQTtNRKiBCRWGBJfjOk56W7fyFUpiYi9fSTWTzoEMbUkn3J4gB0IMniIEVeAGR1/rzFQogzD5MxvQ==} rrweb-cssom@0.8.0: resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} @@ -5633,15 +6527,15 @@ packages: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} - scheduler@0.26.0: - resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} engines: {node: '>=10'} hasBin: true @@ -5676,8 +6570,8 @@ packages: engines: {node: '>= 0.10'} hasBin: true - sharp@0.34.2: - resolution: {integrity: sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==} + 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: @@ -5714,9 +6608,6 @@ 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==} - slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -5742,6 +6633,7 @@ 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==} @@ -5749,8 +6641,8 @@ packages: spdx-expression-parse@4.0.0: resolution: {integrity: sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==} - spdx-license-ids@3.0.21: - resolution: {integrity: sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==} + spdx-license-ids@3.0.22: + resolution: {integrity: sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==} split-on-first@1.1.0: resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} @@ -5770,8 +6662,8 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} - std-env@3.9.0: - resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} stop-iteration-iterator@1.1.0: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} @@ -5789,10 +6681,6 @@ 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'} @@ -5838,8 +6726,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: @@ -5854,8 +6742,8 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - strip-literal@3.0.0: - resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} + strip-literal@3.1.0: + resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} styled-jsx@5.1.6: resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} @@ -5902,15 +6790,15 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - synckit@0.11.8: - resolution: {integrity: sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A==} + synckit@0.11.11: + resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} engines: {node: ^14.18.0 || >=16.0.0} tailwind-merge@2.6.0: resolution: {integrity: sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==} - tailwindcss@3.4.17: - resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} + tailwindcss@3.4.18: + resolution: {integrity: sha512-6A2rnmW5xZMdw11LYjhcI5846rt9pbLSabY5XPxo+XWdxwZaFEn47Go4NzFiHu9sNNmr/kXivP1vStfvMaK1GQ==} engines: {node: '>=14.0.0'} hasBin: true @@ -5933,8 +6821,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: @@ -5945,8 +6833,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: @@ -5956,8 +6844,8 @@ packages: resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} hasBin: true - 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: @@ -5995,20 +6883,6 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - ts-node@10.9.2: - resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true - tsconfck@3.1.6: resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} engines: {node: ^18 || >=20} @@ -6125,23 +6999,23 @@ 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'} unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - unrs-resolver@1.10.1: - resolution: {integrity: sha512-EFrL7Hw4kmhZdwWO3dwwFJo6hO3FXuQ6Bg8BK/faHZ9m1YxqBS31BNSTxklIQkxK/4LlV8zTYnPsIRLBzTzjCA==} + unrs-resolver@1.11.1: + resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} - unstorage@1.16.0: - resolution: {integrity: sha512-WQ37/H5A7LcRPWfYOrDa1Ys02xAbpPJq6q5GkO88FBXVSQzHd7+BjEwfRqyaSWCv9MbsJy058GWjjPjcJ16GGA==} + unstorage@1.17.1: + resolution: {integrity: sha512-KKGwRTT0iVBCErKemkJCLs7JdxNVfqTPc/85ae1XES0+bsHbc/sFBfVi5kJp156cc51BHinIH2l3k0EZ24vOBQ==} peerDependencies: '@azure/app-configuration': ^1.8.0 '@azure/cosmos': ^4.2.0 @@ -6151,10 +7025,11 @@ 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 + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 '@planetscale/database': ^1.19.0 '@upstash/redis': ^1.34.3 '@vercel/blob': '>=0.27.1' + '@vercel/functions': ^2.2.12 || ^3.0.0 '@vercel/kv': ^1.0.1 aws4fetch: ^1.0.20 db0: '>=0.2.1' @@ -6186,6 +7061,8 @@ packages: optional: true '@vercel/blob': optional: true + '@vercel/functions': + optional: true '@vercel/kv': optional: true aws4fetch: @@ -6199,8 +7076,8 @@ packages: uploadthing: optional: true - update-browserslist-db@1.1.3: - resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + update-browserslist-db@1.1.4: + resolution: {integrity: sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -6240,9 +7117,6 @@ packages: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true - v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - valtio@1.13.2: resolution: {integrity: sha512-Qik0o+DSy741TmkqmRfjq+0xpZBXi/Y6+fXZLn0xNF1z/waFMbE3rkivv5Zcf9RrMUp6zswf2J7sbh2KBlba5A==} engines: {node: '>=12.20.0'} @@ -6275,6 +7149,14 @@ packages: typescript: optional: true + viem@2.38.3: + resolution: {integrity: sha512-By2TutLv07iNHHtWqHHzjGipevYsfGqT7KQbGEmqLco1qTJxKnvBbSviqiu6/v/9REV6Q/FpmIxf2Z7/l5AbcQ==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + vite-node@3.2.4: resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -6288,8 +7170,8 @@ packages: vite: optional: true - vite@6.3.5: - resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==} + vite@6.4.1: + resolution: {integrity: sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: @@ -6360,8 +7242,8 @@ packages: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} - wagmi@2.15.6: - resolution: {integrity: sha512-tR4tm+7eE0UloQe1oi4hUIjIDyjv5ImQlzq/QcvvfJYWF/EquTfGrmht6+nTYGCIeSzeEvbK90KgWyNqa+HD7Q==} + wagmi@2.18.2: + resolution: {integrity: sha512-9jFip+0ZfjMBxT72m02MZD2+VmQQ/UmqZhHl+98N9HEqXLn765fIu45QPV85DAnQqIHD81gvY3vTvfWt16A5yQ==} peerDependencies: '@tanstack/react-query': '>=5.0.0' react: '>=18' @@ -6531,8 +7413,8 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yaml@2.8.0: - resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==} + yaml@2.8.1: + resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} engines: {node: '>= 14.6'} hasBin: true @@ -6544,10 +7426,6 @@ packages: resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} engines: {node: '>=8'} - yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -6558,6 +7436,9 @@ packages: zod@3.25.71: resolution: {integrity: sha512-BsBc/NPk7h8WsUWYWYL+BajcJPY8YhjelaWu2NMLuzgraKAz4Lb4/6K11g9jpuDetjMiqhZ6YaexFLOC0Ogi3Q==} + zod@4.1.12: + resolution: {integrity: sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==} + zustand@5.0.0: resolution: {integrity: sha512-LE+VcmbartOPM+auOjCCLQOsQ05zUTp8RkgwRzefUk+2jISdMMFnxvyTjA4YNWr5ZGXYbVsEMZosttuxUBkojQ==} engines: {node: '>=12.20.0'} @@ -6576,21 +7457,52 @@ 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 + + zustand@5.0.8: + resolution: {integrity: sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw==} + 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': {} '@alloc/quick-lru@5.2.0': {} - '@ampproject/remapping@2.3.0': - dependencies: - '@jridgewell/gen-mapping': 0.3.12 - '@jridgewell/trace-mapping': 0.3.29 - '@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 @@ -6601,76 +7513,76 @@ 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.0': + '@babel/core@7.28.4': dependencies: - '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.0 + '@babel/generator': 7.28.3 '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) - '@babel/helpers': 7.27.6 - '@babel/parser': 7.28.0 + '@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.0 - '@babel/types': 7.28.0 + '@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 transitivePeerDependencies: - supports-color - '@babel/generator@7.28.0': + '@babel/generator@7.28.3': dependencies: - '@babel/parser': 7.28.0 - '@babel/types': 7.28.0 - '@jridgewell/gen-mapping': 0.3.12 - '@jridgewell/trace-mapping': 0.3.29 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 '@babel/helper-annotate-as-pure@7.27.3': dependencies: - '@babel/types': 7.28.0 + '@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.1 + browserslist: 4.27.0 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.27.1(@babel/core@7.28.0)': + '@babel/helper-create-class-features-plugin@7.28.3(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0) + '@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.0 + '@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.0)': + '@babel/helper-create-regexp-features-plugin@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0)': + '@babel/helper-define-polyfill-provider@0.6.5(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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 + resolve: 1.22.11 transitivePeerDependencies: - supports-color @@ -6678,55 +7590,55 @@ snapshots: '@babel/helper-member-expression-to-functions@7.27.1': dependencies: - '@babel/traverse': 7.28.0 - '@babel/types': 7.28.0 + '@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.0 - '@babel/types': 7.28.0 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.27.3(@babel/core@7.28.0)': + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-module-imports': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.0 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color '@babel/helper-optimise-call-expression@7.27.1': dependencies: - '@babel/types': 7.28.0 + '@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.0)': + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-wrap-function': 7.27.1 - '@babel/traverse': 7.28.0 + '@babel/helper-wrap-function': 7.28.3 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.0)': + '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: - '@babel/traverse': 7.28.0 - '@babel/types': 7.28.0 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 transitivePeerDependencies: - supports-color @@ -6736,608 +7648,653 @@ snapshots: '@babel/helper-validator-option@7.27.1': {} - '@babel/helper-wrap-function@7.27.1': + '@babel/helper-wrap-function@7.28.3': dependencies: '@babel/template': 7.27.2 - '@babel/traverse': 7.28.0 - '@babel/types': 7.28.0 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/helpers@7.27.6': + '@babel/helpers@7.28.4': dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.28.0 + '@babel/types': 7.28.4 - '@babel/parser@7.28.0': + '@babel/parser@7.28.4': dependencies: - '@babel/types': 7.28.0 + '@babel/types': 7.28.4 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.0 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0)': + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0)': + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0) + '@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.27.1(@babel/core@7.28.0)': + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.0 + '@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.0)': + '@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.0 + '@babel/core': 7.28.4 - '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0)': + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.0) + '@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.0)': + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0)': + '@babel/plugin-transform-async-generator-functions@7.28.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0) - '@babel/traverse': 7.28.0 + '@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.0)': + '@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0) + '@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.0)': + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-block-scoping@7.28.0(@babel/core@7.28.0)': + '@babel/plugin-transform-block-scoping@7.28.4(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.0) + '@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.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-class-static-block@7.28.3(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.0) + '@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.0(@babel/core@7.28.0)': + '@babel/plugin-transform-classes@7.28.4(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0) - '@babel/traverse': 7.28.0 + '@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.0)': + '@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0)': + '@babel/plugin-transform-destructuring@7.28.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.0 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-dotall-regex@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-dotall-regex@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.0) + '@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.0)': + '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0)': + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.0) + '@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.0)': + '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0)': + '@babel/plugin-transform-explicit-resource-management@7.28.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.0) + '@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.0)': + '@babel/plugin-transform-exponentiation-operator@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0)': + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0)': + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.0 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-json-strings@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-json-strings@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0)': + '@babel/plugin-transform-logical-assignment-operators@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0)': + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) + '@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.0)': + '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) + '@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.0)': + '@babel/plugin-transform-modules-systemjs@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) + '@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.0 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) + '@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.0)': + '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.0) + '@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.0)': + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0)': + '@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0)': + '@babel/plugin-transform-object-rest-spread@7.28.4(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.0) - '@babel/traverse': 7.28.0 + '@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.0)': + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.0) + '@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.0)': + '@babel/plugin-transform-optional-catch-binding@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-optional-chaining@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-optional-chaining@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0)': + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.0) + '@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.0)': + '@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.0) + '@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.0)': + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0)': + '@babel/plugin-transform-react-constant-elements@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0)': + '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0)': + '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 - '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.0) + '@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@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0) - '@babel/types': 7.28.0 + '@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.0)': + '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0(@babel/core@7.28.0)': + '@babel/plugin-transform-regenerator@7.28.4(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.0) + '@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.0)': + '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-spread@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-spread@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0)': + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-typescript@7.28.0(@babel/core@7.28.0)': + '@babel/plugin-transform-typescript@7.28.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.0) + '@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.0) + '@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.0)': + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0)': + '@babel/plugin-transform-unicode-property-regex@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.0) + '@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.0)': + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.0) + '@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.0)': + '@babel/plugin-transform-unicode-sets-regex@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.0) + '@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.0(@babel/core@7.28.0)': + '@babel/preset-env@7.28.3(@babel/core@7.28.4)': dependencies: - '@babel/compat-data': 7.28.0 - '@babel/core': 7.28.0 + '@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.0) - '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.0) - '@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.28.0) - '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-async-generator-functions': 7.28.0(@babel/core@7.28.0) - '@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-block-scoping': 7.28.0(@babel/core@7.28.0) - '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-class-static-block': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-classes': 7.28.0(@babel/core@7.28.0) - '@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.0) - '@babel/plugin-transform-dotall-regex': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-explicit-resource-management': 7.28.0(@babel/core@7.28.0) - '@babel/plugin-transform-exponentiation-operator': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-json-strings': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-logical-assignment-operators': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-modules-systemjs': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-object-rest-spread': 7.28.0(@babel/core@7.28.0) - '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.0) - '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-regenerator': 7.28.0(@babel/core@7.28.0) - '@babel/plugin-transform-regexp-modifiers': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-spread': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-unicode-property-regex': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-unicode-sets-regex': 7.27.1(@babel/core@7.28.0) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.28.0) - babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.0) - babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.0) - babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.0) - core-js-compat: 3.43.0 + '@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.46.0 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.28.0)': + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/types': 7.28.0 + '@babel/types': 7.28.4 esutils: 2.0.3 - '@babel/preset-react@7.27.1(@babel/core@7.28.0)': + '@babel/preset-react@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0) - '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.28.0) + '@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.0)': + '@babel/preset-typescript@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@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.0) - '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.0) + '@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.27.6': {} + '@babel/runtime@7.28.4': {} '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.0 - '@babel/types': 7.28.0 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 + + '@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.4 + '@babel/template': 7.27.2 + '@babel/types': 7.28.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@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.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@3.25.71)': + 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.8.3)(zod@3.25.71) + preact: 10.24.2 + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + zustand: 5.0.3(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)) + transitivePeerDependencies: + - '@types/react' + - bufferutil + - immer + - react + - typescript + - use-sync-external-store + - utf-8-validate + - zod - '@babel/traverse@7.28.0': + '@coinbase/cdp-sdk@1.38.4(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.0 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.0 - '@babel/template': 7.27.2 - '@babel/types': 7.28.0 - debug: 4.4.1 + '@solana-program/system': 0.8.1(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + '@solana-program/token': 0.6.0(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.98.4(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.71) + 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.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + zod: 3.25.71 transitivePeerDependencies: - - supports-color - - '@babel/types@7.28.0': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 + - bufferutil + - debug + - encoding + - fastestsmallesttextencoderdecoder + - typescript + - utf-8-validate + - ws - '@coinbase/cdp-sdk@1.38.0(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10)': + '@coinbase/cdp-sdk@1.38.4(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: - '@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) + '@solana-program/system': 0.8.1(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + '@solana-program/token': 0.6.0(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.98.4(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.71) - axios: 1.10.0 - axios-retry: 4.5.0(axios@1.10.0) - jose: 6.0.11 + 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.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) zod: 3.25.71 transitivePeerDependencies: - bufferutil @@ -7346,22 +8303,23 @@ snapshots: - fastestsmallesttextencoderdecoder - typescript - utf-8-validate + - ws - '@coinbase/onchainkit@0.38.15(@tanstack/query-core@5.81.5)(@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.71)': + '@coinbase/onchainkit@0.38.19(@farcaster/miniapp-sdk@0.2.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@3.25.71)': dependencies: - '@farcaster/frame-sdk': 0.0.60(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) - '@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.71))(@wagmi/core@2.17.3(@tanstack/query-core@5.81.5)(@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.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)) - '@tanstack/react-query': 5.81.5(react@19.1.0) - '@wagmi/core': 2.17.3(@tanstack/query-core@5.81.5)(@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.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)) + '@farcaster/frame-sdk': 0.1.12(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + '@farcaster/miniapp-wagmi-connector': 1.1.0(@farcaster/miniapp-sdk@0.2.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)) + '@tanstack/react-query': 5.90.5(react@19.2.0) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)) clsx: 2.1.1 graphql: 16.11.0 graphql-request: 6.1.0(graphql@16.11.0) qrcode: 1.5.4 - react: 19.1.0 - react-dom: 19.1.0(react@19.1.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) tailwind-merge: 2.6.0 - viem: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) - wagmi: 2.15.6(@tanstack/query-core@5.81.5)(@tanstack/react-query@5.81.5(react@19.1.0))(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + wagmi: 2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -7371,6 +8329,7 @@ snapshots: - '@azure/storage-blob' - '@capacitor/preferences' - '@deno/kv' + - '@farcaster/miniapp-sdk' - '@netlify/blobs' - '@planetscale/database' - '@react-native-async-storage/async-storage' @@ -7378,6 +8337,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -7401,17 +8361,30 @@ snapshots: eth-json-rpc-filters: 6.0.1 eventemitter3: 5.0.1 keccak: 3.0.4 - preact: 10.26.9 + preact: 10.27.2 sha.js: 2.4.12 transitivePeerDependencies: - supports-color - '@coinbase/wallet-sdk@4.3.3': + '@coinbase/wallet-sdk@4.3.6(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@3.25.71)': dependencies: - '@noble/hashes': 1.8.0 + '@noble/hashes': 1.4.0 clsx: 1.2.1 eventemitter3: 5.0.1 - preact: 10.26.9 + idb-keyval: 6.2.1 + ox: 0.6.9(typescript@5.8.3)(zod@3.25.71) + preact: 10.24.2 + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + zustand: 5.0.3(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)) + transitivePeerDependencies: + - '@types/react' + - bufferutil + - immer + - react + - typescript + - use-sync-external-store + - utf-8-validate + - zod '@craftamap/esbuild-plugin-html@0.9.0(bufferutil@4.0.9)(esbuild@0.25.5)(utf-8-validate@5.0.10)': dependencies: @@ -7424,21 +8397,16 @@ snapshots: - supports-color - utf-8-validate - '@cspotcode/source-map-support@0.8.1': - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - optional: true - - '@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 @@ -7449,22 +8417,22 @@ snapshots: '@csstools/css-tokenizer@3.0.4': {} - '@ecies/ciphers@0.2.3(@noble/ciphers@1.3.0)': + '@ecies/ciphers@0.2.4(@noble/ciphers@1.3.0)': dependencies: '@noble/ciphers': 1.3.0 - '@emnapi/core@1.4.3': + '@emnapi/core@1.6.0': dependencies: - '@emnapi/wasi-threads': 1.0.2 + '@emnapi/wasi-threads': 1.1.0 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.4.3': + '@emnapi/runtime@1.6.0': dependencies: tslib: 2.8.1 optional: true - '@emnapi/wasi-threads@1.0.2': + '@emnapi/wasi-threads@1.1.0': dependencies: tslib: 2.8.1 optional: true @@ -7472,7 +8440,7 @@ snapshots: '@es-joy/jsdoccomment@0.50.2': dependencies: '@types/estree': 1.0.8 - '@typescript-eslint/types': 8.35.1 + '@typescript-eslint/types': 8.46.2 comment-parser: 1.4.1 esquery: 1.6.0 jsdoc-type-pratt-parser: 4.1.0 @@ -7621,35 +8589,33 @@ snapshots: '@esbuild/win32-x64@0.25.5': optional: true - '@eslint-community/eslint-utils@4.7.0(eslint@9.30.1(jiti@1.21.7))': + '@eslint-community/eslint-utils@4.9.0(eslint@9.38.0(jiti@1.21.7))': dependencies: - eslint: 9.30.1(jiti@1.21.7) + eslint: 9.38.0(jiti@1.21.7) eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.12.1': {} + '@eslint-community/regexpp@4.12.2': {} - '@eslint/config-array@0.21.0': + '@eslint/config-array@0.21.1': dependencies: - '@eslint/object-schema': 2.1.6 - debug: 4.4.1 + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 minimatch: 3.1.2 transitivePeerDependencies: - supports-color - '@eslint/config-helpers@0.3.0': {} - - '@eslint/core@0.14.0': + '@eslint/config-helpers@0.4.1': dependencies: - '@types/json-schema': 7.0.15 + '@eslint/core': 0.16.0 - '@eslint/core@0.15.1': + '@eslint/core@0.16.0': dependencies: '@types/json-schema': 7.0.15 '@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 @@ -7660,13 +8626,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.30.1': {} + '@eslint/js@9.38.0': {} - '@eslint/object-schema@2.1.6': {} + '@eslint/object-schema@2.1.7': {} - '@eslint/plugin-kit@0.3.3': + '@eslint/plugin-kit@0.4.0': dependencies: - '@eslint/core': 0.15.1 + '@eslint/core': 0.16.0 levn: 0.4.1 '@ethereumjs/common@3.2.0': @@ -7689,9 +8655,23 @@ snapshots: ethereum-cryptography: 2.2.1 micro-ftch: 0.3.1 - '@farcaster/frame-core@0.1.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': + '@farcaster/frame-sdk@0.1.12(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)': + dependencies: + '@farcaster/miniapp-sdk': 0.2.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + '@farcaster/quick-auth': 0.0.8(typescript@5.8.3) + comlink: 4.4.2 + eventemitter3: 5.0.1 + ox: 0.4.4(typescript@5.8.3)(zod@3.25.71) + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + '@farcaster/miniapp-core@0.4.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': dependencies: - '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.4(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.71) zod: 3.25.71 transitivePeerDependencies: @@ -7700,10 +8680,10 @@ snapshots: - typescript - utf-8-validate - '@farcaster/frame-sdk@0.0.60(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)': + '@farcaster/miniapp-sdk@0.2.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)': dependencies: - '@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) + '@farcaster/miniapp-core': 0.4.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@farcaster/quick-auth': 0.0.6(typescript@5.8.3) comlink: 4.4.2 eventemitter3: 5.0.1 ox: 0.4.4(typescript@5.8.3)(zod@3.25.71) @@ -7714,158 +8694,185 @@ snapshots: - utf-8-validate - zod - '@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.71))(@wagmi/core@2.17.3(@tanstack/query-core@5.81.5)(@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.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))': + '@farcaster/miniapp-wagmi-connector@1.1.0(@farcaster/miniapp-sdk@0.2.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))': dependencies: - '@farcaster/frame-sdk': 0.0.60(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) - '@wagmi/core': 2.17.3(@tanstack/query-core@5.81.5)(@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.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)) - viem: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + '@farcaster/miniapp-sdk': 0.2.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + + '@farcaster/quick-auth@0.0.6(typescript@5.8.3)': + dependencies: + jose: 5.10.0 + typescript: 5.8.3 + zod: 3.25.71 - '@farcaster/quick-auth@0.0.5(typescript@5.8.3)': + '@farcaster/quick-auth@0.0.8(typescript@5.8.3)': dependencies: jose: 5.10.0 typescript: 5.8.3 zod: 3.25.71 + '@gemini-wallet/core@0.2.0(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))': + dependencies: + '@metamask/rpc-errors': 7.0.2 + eventemitter3: 5.0.1 + viem: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + transitivePeerDependencies: + - supports-color + + '@gemini-wallet/core@0.2.0(viem@2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))': + dependencies: + '@metamask/rpc-errors': 7.0.2 + eventemitter3: 5.0.1 + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + transitivePeerDependencies: + - supports-color + '@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.0)': + '@heroicons/react@2.2.0(react@19.2.0)': dependencies: - react: 19.1.0 + react: 19.2.0 - '@hono/node-server@1.15.0(hono@4.8.3)': + '@hono/node-server@1.19.5(hono@4.10.2)': dependencies: - hono: 4.8.3 + hono: 4.10.2 '@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/module-importer@1.0.1': {} - '@humanwhocodes/retry@0.3.1': {} - '@humanwhocodes/retry@0.4.3': {} - '@img/sharp-darwin-arm64@0.34.2': + '@img/colour@1.0.0': + optional: true + + '@img/sharp-darwin-arm64@0.34.4': optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.1.0 + '@img/sharp-libvips-darwin-arm64': 1.2.3 optional: true - '@img/sharp-darwin-x64@0.34.2': + '@img/sharp-darwin-x64@0.34.4': optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.1.0 + '@img/sharp-libvips-darwin-x64': 1.2.3 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.3': optional: true - '@img/sharp-libvips-darwin-arm64@1.1.0': + '@img/sharp-libvips-darwin-x64@1.2.3': optional: true - '@img/sharp-libvips-darwin-x64@1.1.0': + '@img/sharp-libvips-linux-arm64@1.2.3': optional: true - '@img/sharp-libvips-linux-arm64@1.1.0': + '@img/sharp-libvips-linux-arm@1.2.3': optional: true - '@img/sharp-libvips-linux-arm@1.1.0': + '@img/sharp-libvips-linux-ppc64@1.2.3': optional: true - '@img/sharp-libvips-linux-ppc64@1.1.0': + '@img/sharp-libvips-linux-s390x@1.2.3': optional: true - '@img/sharp-libvips-linux-s390x@1.1.0': + '@img/sharp-libvips-linux-x64@1.2.3': optional: true - '@img/sharp-libvips-linux-x64@1.1.0': + '@img/sharp-libvips-linuxmusl-arm64@1.2.3': optional: true - '@img/sharp-libvips-linuxmusl-arm64@1.1.0': + '@img/sharp-libvips-linuxmusl-x64@1.2.3': optional: true - '@img/sharp-libvips-linuxmusl-x64@1.1.0': + '@img/sharp-linux-arm64@0.34.4': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.3 optional: true - '@img/sharp-linux-arm64@0.34.2': + '@img/sharp-linux-arm@0.34.4': optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.1.0 + '@img/sharp-libvips-linux-arm': 1.2.3 optional: true - '@img/sharp-linux-arm@0.34.2': + '@img/sharp-linux-ppc64@0.34.4': optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.1.0 + '@img/sharp-libvips-linux-ppc64': 1.2.3 optional: true - '@img/sharp-linux-s390x@0.34.2': + '@img/sharp-linux-s390x@0.34.4': optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.1.0 + '@img/sharp-libvips-linux-s390x': 1.2.3 optional: true - '@img/sharp-linux-x64@0.34.2': + '@img/sharp-linux-x64@0.34.4': optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.1.0 + '@img/sharp-libvips-linux-x64': 1.2.3 optional: true - '@img/sharp-linuxmusl-arm64@0.34.2': + '@img/sharp-linuxmusl-arm64@0.34.4': optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.3 optional: true - '@img/sharp-linuxmusl-x64@0.34.2': + '@img/sharp-linuxmusl-x64@0.34.4': optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + '@img/sharp-libvips-linuxmusl-x64': 1.2.3 optional: true - '@img/sharp-wasm32@0.34.2': + '@img/sharp-wasm32@0.34.4': dependencies: - '@emnapi/runtime': 1.4.3 + '@emnapi/runtime': 1.6.0 optional: true - '@img/sharp-win32-arm64@0.34.2': + '@img/sharp-win32-arm64@0.34.4': optional: true - '@img/sharp-win32-ia32@0.34.2': + '@img/sharp-win32-ia32@0.34.4': optional: true - '@img/sharp-win32-x64@0.34.2': + '@img/sharp-win32-x64@0.34.4': optional: true '@isaacs/cliui@8.0.2': 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 - '@jridgewell/gen-mapping@0.3.12': + '@jridgewell/gen-mapping@0.3.13': dependencies: - '@jridgewell/sourcemap-codec': 1.5.4 - '@jridgewell/trace-mapping': 0.3.29 + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/resolve-uri@3.1.2': {} + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/sourcemap-codec@1.5.4': {} + '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/trace-mapping@0.3.29': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.4 + '@jridgewell/sourcemap-codec@1.5.5': {} - '@jridgewell/trace-mapping@0.3.9': + '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.4 - optional: true + '@jridgewell/sourcemap-codec': 1.5.5 - '@lit-labs/ssr-dom-shim@1.3.0': {} + '@lit-labs/ssr-dom-shim@1.4.0': {} - '@lit/reactive-element@2.1.0': + '@lit/reactive-element@2.1.1': dependencies: - '@lit-labs/ssr-dom-shim': 1.3.0 + '@lit-labs/ssr-dom-shim': 1.4.0 '@metamask/eth-json-rpc-provider@1.0.1': dependencies: @@ -7907,7 +8914,7 @@ snapshots: '@metamask/onboarding@1.0.1': dependencies: - bowser: 2.11.0 + bowser: 2.12.1 '@metamask/providers@16.1.0': dependencies: @@ -7933,17 +8940,29 @@ snapshots: transitivePeerDependencies: - supports-color + '@metamask/rpc-errors@7.0.2': + dependencies: + '@metamask/utils': 11.8.1 + fast-safe-stringify: 2.1.1 + transitivePeerDependencies: + - supports-color + '@metamask/safe-event-emitter@2.0.0': {} '@metamask/safe-event-emitter@3.1.2': {} - '@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-analytics@0.0.5': + dependencies: + openapi-fetch: 0.13.8 + + '@metamask/sdk-communication-layer@0.33.1(cross-fetch@4.1.0)(eciesjs@0.4.16)(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 date-fns: 2.30.0 - debug: 4.4.1 - eciesjs: 0.4.15 + debug: 4.3.4 + eciesjs: 0.4.16 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) @@ -7952,22 +8971,23 @@ 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)(utf-8-validate@5.0.10)': + '@metamask/sdk@0.33.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: - '@babel/runtime': 7.27.6 + '@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)(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)(eciesjs@0.4.16)(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.11.0 + bowser: 2.12.1 cross-fetch: 4.1.0 - debug: 4.4.1 - eciesjs: 0.4.15 + debug: 4.3.4 + eciesjs: 0.4.16 eth-rpc-errors: 4.0.3 eventemitter2: 6.4.9 obj-multiplex: 1.0.0 @@ -7985,12 +9005,28 @@ snapshots: '@metamask/superstruct@3.2.1': {} + '@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 + '@types/lodash': 4.17.20 + debug: 4.4.3 + lodash: 4.17.21 + pony-cause: 2.1.11 + semver: 7.7.3 + uuid: 9.0.1 + transitivePeerDependencies: + - supports-color + '@metamask/utils@5.0.2': dependencies: '@ethereumjs/tx': 4.2.0 '@types/debug': 4.1.12 - debug: 4.4.1 - semver: 7.7.2 + debug: 4.4.3 + semver: 7.7.3 superstruct: 1.0.4 transitivePeerDependencies: - supports-color @@ -8002,9 +9038,9 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 '@types/debug': 4.1.12 - debug: 4.4.1 + debug: 4.4.3 pony-cause: 2.1.11 - semver: 7.7.2 + semver: 7.7.3 uuid: 9.0.1 transitivePeerDependencies: - supports-color @@ -8016,74 +9052,48 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 '@types/debug': 4.1.12 - debug: 4.4.1 + debug: 4.4.3 pony-cause: 2.1.11 - semver: 7.7.2 + semver: 7.7.3 uuid: 9.0.1 transitivePeerDependencies: - supports-color - '@napi-rs/wasm-runtime@0.2.11': + '@napi-rs/wasm-runtime@0.2.12': dependencies: - '@emnapi/core': 1.4.3 - '@emnapi/runtime': 1.4.3 - '@tybys/wasm-util': 0.9.0 + '@emnapi/core': 1.6.0 + '@emnapi/runtime': 1.6.0 + '@tybys/wasm-util': 0.10.1 optional: true - '@next/env@15.3.4': {} - - '@next/env@15.4.0-canary.113': {} + '@next/env@15.5.6': {} '@next/eslint-plugin-next@15.1.7': dependencies: fast-glob: 3.3.1 - '@next/swc-darwin-arm64@15.3.4': - optional: true - - '@next/swc-darwin-arm64@15.4.0-canary.113': - optional: true - - '@next/swc-darwin-x64@15.3.4': - optional: true - - '@next/swc-darwin-x64@15.4.0-canary.113': - optional: true - - '@next/swc-linux-arm64-gnu@15.3.4': - optional: true - - '@next/swc-linux-arm64-gnu@15.4.0-canary.113': - optional: true - - '@next/swc-linux-arm64-musl@15.3.4': + '@next/swc-darwin-arm64@15.5.6': optional: true - '@next/swc-linux-arm64-musl@15.4.0-canary.113': + '@next/swc-darwin-x64@15.5.6': optional: true - '@next/swc-linux-x64-gnu@15.3.4': + '@next/swc-linux-arm64-gnu@15.5.6': optional: true - '@next/swc-linux-x64-gnu@15.4.0-canary.113': + '@next/swc-linux-arm64-musl@15.5.6': optional: true - '@next/swc-linux-x64-musl@15.3.4': + '@next/swc-linux-x64-gnu@15.5.6': optional: true - '@next/swc-linux-x64-musl@15.4.0-canary.113': + '@next/swc-linux-x64-musl@15.5.6': optional: true - '@next/swc-win32-arm64-msvc@15.3.4': + '@next/swc-win32-arm64-msvc@15.5.6': optional: true - '@next/swc-win32-arm64-msvc@15.4.0-canary.113': - optional: true - - '@next/swc-win32-x64-msvc@15.3.4': - optional: true - - '@next/swc-win32-x64-msvc@15.4.0-canary.113': + '@next/swc-win32-x64-msvc@15.5.6': optional: true '@noble/ciphers@1.2.1': {} @@ -8102,10 +9112,18 @@ snapshots: dependencies: '@noble/hashes': 1.7.1 + '@noble/curves@1.9.1': + dependencies: + '@noble/hashes': 1.8.0 + '@noble/curves@1.9.2': dependencies: '@noble/hashes': 1.8.0 + '@noble/curves@1.9.7': + dependencies: + '@noble/hashes': 1.8.0 + '@noble/hashes@1.4.0': {} '@noble/hashes@1.7.0': {} @@ -8133,13 +9151,13 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@pkgr/core@0.2.7': {} + '@pkgr/core@0.2.9': {} '@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.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) transitivePeerDependencies: - bufferutil - typescript @@ -8150,20 +9168,20 @@ snapshots: dependencies: big.js: 6.2.2 dayjs: 1.11.13 - viem: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) transitivePeerDependencies: - bufferutil - typescript - utf-8-validate - zod - '@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.71)': + '@reown/appkit-controllers@1.7.8(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) '@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.71) - valtio: 1.13.2(@types/react@19.1.8)(react@19.1.0) - viem: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + valtio: 1.13.2(@types/react@19.2.2)(react@19.2.0) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -8179,6 +9197,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -8191,14 +9210,14 @@ snapshots: - utf-8-validate - zod - '@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.71)': + '@reown/appkit-pay@1.7.8(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) - '@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.71) - '@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.71) - '@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.71) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + '@reown/appkit-ui': 1.7.8(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + '@reown/appkit-utils': 1.7.8(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0))(zod@3.25.71) lit: 3.3.0 - valtio: 1.13.2(@types/react@19.1.8)(react@19.1.0) + valtio: 1.13.2(@types/react@19.2.2)(react@19.2.0) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -8214,6 +9233,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -8230,12 +9250,12 @@ snapshots: dependencies: buffer: 6.0.3 - '@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.71)': + '@reown/appkit-scaffold-ui@1.7.8(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0))(zod@3.25.71)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) - '@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.71) - '@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.71) - '@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.71) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + '@reown/appkit-ui': 1.7.8(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + '@reown/appkit-utils': 1.7.8(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0))(zod@3.25.71) '@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: @@ -8253,6 +9273,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -8266,10 +9287,10 @@ snapshots: - valtio - zod - '@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.71)': + '@reown/appkit-ui@1.7.8(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) - '@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.71) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) '@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 @@ -8288,6 +9309,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -8300,16 +9322,16 @@ snapshots: - utf-8-validate - zod - '@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.71)': + '@reown/appkit-utils@1.7.8(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0))(zod@3.25.71)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) - '@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.71) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) '@reown/appkit-polyfills': 1.7.8 '@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(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) - valtio: 1.13.2(@types/react@19.1.8)(react@19.1.0) - viem: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + valtio: 1.13.2(@types/react@19.2.2)(react@19.2.0) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -8325,6 +9347,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -8348,21 +9371,21 @@ snapshots: - typescript - utf-8-validate - '@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.71)': + '@reown/appkit@1.7.8(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) - '@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.71) - '@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.71) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + '@reown/appkit-pay': 1.7.8(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) '@reown/appkit-polyfills': 1.7.8 - '@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.71) - '@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.71) - '@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.71) + '@reown/appkit-scaffold-ui': 1.7.8(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0))(zod@3.25.71) + '@reown/appkit-ui': 1.7.8(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + '@reown/appkit-utils': 1.7.8(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0))(zod@3.25.71) '@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.71) bs58: 6.0.0 - valtio: 1.13.2(@types/react@19.1.8)(react@19.1.0) - viem: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + valtio: 1.13.2(@types/react@19.2.2)(react@19.2.0) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -8378,6 +9401,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -8390,69 +9414,75 @@ snapshots: - utf-8-validate - zod - '@rollup/rollup-android-arm-eabi@4.44.1': + '@rollup/rollup-android-arm-eabi@4.52.5': + optional: true + + '@rollup/rollup-android-arm64@4.52.5': optional: true - '@rollup/rollup-android-arm64@4.44.1': + '@rollup/rollup-darwin-arm64@4.52.5': optional: true - '@rollup/rollup-darwin-arm64@4.44.1': + '@rollup/rollup-darwin-x64@4.52.5': optional: true - '@rollup/rollup-darwin-x64@4.44.1': + '@rollup/rollup-freebsd-arm64@4.52.5': optional: true - '@rollup/rollup-freebsd-arm64@4.44.1': + '@rollup/rollup-freebsd-x64@4.52.5': optional: true - '@rollup/rollup-freebsd-x64@4.44.1': + '@rollup/rollup-linux-arm-gnueabihf@4.52.5': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.44.1': + '@rollup/rollup-linux-arm-musleabihf@4.52.5': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.44.1': + '@rollup/rollup-linux-arm64-gnu@4.52.5': optional: true - '@rollup/rollup-linux-arm64-gnu@4.44.1': + '@rollup/rollup-linux-arm64-musl@4.52.5': optional: true - '@rollup/rollup-linux-arm64-musl@4.44.1': + '@rollup/rollup-linux-loong64-gnu@4.52.5': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.44.1': + '@rollup/rollup-linux-ppc64-gnu@4.52.5': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.44.1': + '@rollup/rollup-linux-riscv64-gnu@4.52.5': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.44.1': + '@rollup/rollup-linux-riscv64-musl@4.52.5': optional: true - '@rollup/rollup-linux-riscv64-musl@4.44.1': + '@rollup/rollup-linux-s390x-gnu@4.52.5': optional: true - '@rollup/rollup-linux-s390x-gnu@4.44.1': + '@rollup/rollup-linux-x64-gnu@4.52.5': optional: true - '@rollup/rollup-linux-x64-gnu@4.44.1': + '@rollup/rollup-linux-x64-musl@4.52.5': optional: true - '@rollup/rollup-linux-x64-musl@4.44.1': + '@rollup/rollup-openharmony-arm64@4.52.5': optional: true - '@rollup/rollup-win32-arm64-msvc@4.44.1': + '@rollup/rollup-win32-arm64-msvc@4.52.5': optional: true - '@rollup/rollup-win32-ia32-msvc@4.44.1': + '@rollup/rollup-win32-ia32-msvc@4.52.5': optional: true - '@rollup/rollup-win32-x64-msvc@4.44.1': + '@rollup/rollup-win32-x64-gnu@4.52.5': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.52.5': optional: true '@rtsao/scc@1.1.0': {} - '@rushstack/eslint-patch@1.12.0': {} + '@rushstack/eslint-patch@1.14.0': {} '@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.71)': dependencies: @@ -8467,7 +9497,7 @@ snapshots: '@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.71)': dependencies: '@safe-global/safe-gateway-typescript-sdk': 3.23.1 - viem: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) transitivePeerDependencies: - bufferutil - typescript @@ -8494,7 +9524,7 @@ snapshots: '@scure/bip32@1.7.0': dependencies: - '@noble/curves': 1.9.2 + '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 @@ -8519,15 +9549,31 @@ snapshots: dependencies: '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana-program/token-2022@0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@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/system@0.8.1(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': + dependencies: + '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + + '@solana-program/system@0.8.1(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': + dependencies: + '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(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.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@solana/sysvars@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3))': dependencies: '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/sysvars': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/sysvars': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) '@solana-program/token@0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': dependencies: '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana-program/token@0.6.0(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': + dependencies: + '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + + '@solana-program/token@0.6.0(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': + dependencies: + '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(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.8.3)': dependencies: '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) @@ -8540,6 +9586,18 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder + '@solana/accounts@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/codecs-core': 3.0.3(typescript@5.8.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/rpc-spec': 3.0.3(typescript@5.8.3) + '@solana/rpc-types': 3.0.3(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.8.3)': dependencies: '@solana/assertions': 2.3.0(typescript@5.8.3) @@ -8551,47 +9609,39 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/assertions@2.3.0(typescript@5.8.3)': + '@solana/addresses@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/errors': 2.3.0(typescript@5.8.3) + '@solana/assertions': 3.0.3(typescript@5.8.3) + '@solana/codecs-core': 3.0.3(typescript@5.8.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/nominal-types': 3.0.3(typescript@5.8.3) typescript: 5.8.3 - - '@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.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) - bigint-buffer: 1.1.5 - bignumber.js: 9.3.0 transitivePeerDependencies: - - bufferutil - - encoding - - typescript - - utf-8-validate + - fastestsmallesttextencoderdecoder - '@solana/buffer-layout@4.0.1': + '@solana/assertions@2.3.0(typescript@5.8.3)': dependencies: - buffer: 6.0.3 + '@solana/errors': 2.3.0(typescript@5.8.3) + typescript: 5.8.3 - '@solana/codecs-core@2.0.0-rc.1(typescript@5.8.3)': + '@solana/assertions@3.0.3(typescript@5.8.3)': dependencies: - '@solana/errors': 2.0.0-rc.1(typescript@5.8.3) + '@solana/errors': 3.0.3(typescript@5.8.3) typescript: 5.8.3 - '@solana/codecs-core@2.1.1(typescript@5.8.3)': + '@solana/buffer-layout@4.0.1': dependencies: - '@solana/errors': 2.1.1(typescript@5.8.3) - typescript: 5.8.3 + buffer: 6.0.3 '@solana/codecs-core@2.3.0(typescript@5.8.3)': dependencies: '@solana/errors': 2.3.0(typescript@5.8.3) typescript: 5.8.3 - '@solana/codecs-data-structures@2.0.0-rc.1(typescript@5.8.3)': + '@solana/codecs-core@3.0.3(typescript@5.8.3)': dependencies: - '@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) + '@solana/errors': 3.0.3(typescript@5.8.3) typescript: 5.8.3 '@solana/codecs-data-structures@2.3.0(typescript@5.8.3)': @@ -8601,16 +9651,11 @@ snapshots: '@solana/errors': 2.3.0(typescript@5.8.3) typescript: 5.8.3 - '@solana/codecs-numbers@2.0.0-rc.1(typescript@5.8.3)': + '@solana/codecs-data-structures@3.0.3(typescript@5.8.3)': dependencies: - '@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.1.1(typescript@5.8.3)': - dependencies: - '@solana/codecs-core': 2.1.1(typescript@5.8.3) - '@solana/errors': 2.1.1(typescript@5.8.3) + '@solana/codecs-core': 3.0.3(typescript@5.8.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.8.3) + '@solana/errors': 3.0.3(typescript@5.8.3) typescript: 5.8.3 '@solana/codecs-numbers@2.3.0(typescript@5.8.3)': @@ -8619,12 +9664,10 @@ snapshots: '@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.8.3)': + '@solana/codecs-numbers@3.0.3(typescript@5.8.3)': dependencies: - '@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 + '@solana/codecs-core': 3.0.3(typescript@5.8.3) + '@solana/errors': 3.0.3(typescript@5.8.3) typescript: 5.8.3 '@solana/codecs-strings@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': @@ -8635,16 +9678,13 @@ snapshots: fastestsmallesttextencoderdecoder: 1.0.22 typescript: 5.8.3 - '@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': + '@solana/codecs-strings@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@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) + '@solana/codecs-core': 3.0.3(typescript@5.8.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.8.3) + '@solana/errors': 3.0.3(typescript@5.8.3) + fastestsmallesttextencoderdecoder: 1.0.22 typescript: 5.8.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder '@solana/codecs@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: @@ -8657,38 +9697,68 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/errors@2.0.0-rc.1(typescript@5.8.3)': + '@solana/codecs@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - chalk: 5.4.1 - commander: 12.1.0 + '@solana/codecs-core': 3.0.3(typescript@5.8.3) + '@solana/codecs-data-structures': 3.0.3(typescript@5.8.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.8.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/options': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) typescript: 5.8.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder - '@solana/errors@2.1.1(typescript@5.8.3)': + '@solana/errors@2.3.0(typescript@5.8.3)': dependencies: - chalk: 5.4.1 - commander: 13.1.0 + chalk: 5.6.2 + commander: 14.0.1 typescript: 5.8.3 - '@solana/errors@2.3.0(typescript@5.8.3)': + '@solana/errors@3.0.3(typescript@5.8.3)': dependencies: - chalk: 5.4.1 - commander: 14.0.1 + chalk: 5.6.2 + commander: 14.0.0 typescript: 5.8.3 '@solana/fast-stable-stringify@2.3.0(typescript@5.8.3)': dependencies: typescript: 5.8.3 + '@solana/fast-stable-stringify@3.0.3(typescript@5.8.3)': + dependencies: + typescript: 5.8.3 + '@solana/functional@2.3.0(typescript@5.8.3)': dependencies: typescript: 5.8.3 + '@solana/functional@3.0.3(typescript@5.8.3)': + dependencies: + typescript: 5.8.3 + + '@solana/instruction-plans@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/instructions': 3.0.3(typescript@5.8.3) + '@solana/promises': 3.0.3(typescript@5.8.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + '@solana/instructions@2.3.0(typescript@5.8.3)': dependencies: '@solana/codecs-core': 2.3.0(typescript@5.8.3) '@solana/errors': 2.3.0(typescript@5.8.3) typescript: 5.8.3 + '@solana/instructions@3.0.3(typescript@5.8.3)': + dependencies: + '@solana/codecs-core': 3.0.3(typescript@5.8.3) + '@solana/errors': 3.0.3(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) @@ -8700,6 +9770,42 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder + '@solana/keys@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': + dependencies: + '@solana/assertions': 3.0.3(typescript@5.8.3) + '@solana/codecs-core': 3.0.3(typescript@5.8.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/nominal-types': 3.0.3(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/accounts': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/codecs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/errors': 2.3.0(typescript@5.8.3) + '@solana/functional': 2.3.0(typescript@5.8.3) + '@solana/instructions': 2.3.0(typescript@5.8.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/programs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc-parsed-types': 2.3.0(typescript@5.8.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.8.3) + '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/signers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/sysvars': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/transaction-confirmation': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + '@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana/accounts': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) @@ -8750,20 +9856,65 @@ snapshots: - fastestsmallesttextencoderdecoder - ws + '@solana/kit@3.0.3(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': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/codecs': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/functional': 3.0.3(typescript@5.8.3) + '@solana/instruction-plans': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/instructions': 3.0.3(typescript@5.8.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/programs': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc-parsed-types': 3.0.3(typescript@5.8.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.8.3) + '@solana/rpc-subscriptions': 3.0.3(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': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/signers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/sysvars': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/transaction-confirmation': 3.0.3(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': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + + '@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/accounts': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/codecs': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/functional': 3.0.3(typescript@5.8.3) + '@solana/instruction-plans': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/instructions': 3.0.3(typescript@5.8.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/programs': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc-parsed-types': 3.0.3(typescript@5.8.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.8.3) + '@solana/rpc-subscriptions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/signers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/sysvars': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/transaction-confirmation': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/transactions': 3.0.3(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.8.3 - '@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': + '@solana/nominal-types@3.0.3(typescript@5.8.3)': dependencies: - '@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.8.3)': dependencies: @@ -8776,6 +9927,17 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder + '@solana/options@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': + dependencies: + '@solana/codecs-core': 3.0.3(typescript@5.8.3) + '@solana/codecs-data-structures': 3.0.3(typescript@5.8.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.8.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/errors': 3.0.3(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + '@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.8.3) @@ -8784,10 +9946,22 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder + '@solana/programs@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/errors': 3.0.3(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + '@solana/promises@2.3.0(typescript@5.8.3)': dependencies: typescript: 5.8.3 + '@solana/promises@3.0.3(typescript@5.8.3)': + dependencies: + typescript: 5.8.3 + '@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) @@ -8805,20 +9979,51 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder + '@solana/rpc-api@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/codecs-core': 3.0.3(typescript@5.8.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc-parsed-types': 3.0.3(typescript@5.8.3) + '@solana/rpc-spec': 3.0.3(typescript@5.8.3) + '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + '@solana/rpc-parsed-types@2.3.0(typescript@5.8.3)': dependencies: typescript: 5.8.3 + '@solana/rpc-parsed-types@3.0.3(typescript@5.8.3)': + dependencies: + typescript: 5.8.3 + '@solana/rpc-spec-types@2.3.0(typescript@5.8.3)': dependencies: typescript: 5.8.3 + '@solana/rpc-spec-types@3.0.3(typescript@5.8.3)': + dependencies: + typescript: 5.8.3 + '@solana/rpc-spec@2.3.0(typescript@5.8.3)': dependencies: '@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-spec@3.0.3(typescript@5.8.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.8.3) + typescript: 5.8.3 + '@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.8.3) @@ -8832,6 +10037,28 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder + '@solana/rpc-subscriptions-api@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc-subscriptions-spec': 3.0.3(typescript@5.8.3) + '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-subscriptions-channel-websocket@2.3.0(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/errors': 2.3.0(typescript@5.8.3) + '@solana/functional': 2.3.0(typescript@5.8.3) + '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.8.3) + '@solana/subscribable': 2.3.0(typescript@5.8.3) + typescript: 5.8.3 + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/rpc-subscriptions-channel-websocket@2.3.0(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana/errors': 2.3.0(typescript@5.8.3) @@ -8850,6 +10077,24 @@ snapshots: typescript: 5.8.3 ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/rpc-subscriptions-channel-websocket@3.0.3(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/functional': 3.0.3(typescript@5.8.3) + '@solana/rpc-subscriptions-spec': 3.0.3(typescript@5.8.3) + '@solana/subscribable': 3.0.3(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@3.0.3(typescript@5.8.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/functional': 3.0.3(typescript@5.8.3) + '@solana/rpc-subscriptions-spec': 3.0.3(typescript@5.8.3) + '@solana/subscribable': 3.0.3(typescript@5.8.3) + typescript: 5.8.3 + ws: 8.18.3(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) @@ -8858,6 +10103,32 @@ snapshots: '@solana/subscribable': 2.3.0(typescript@5.8.3) typescript: 5.8.3 + '@solana/rpc-subscriptions-spec@3.0.3(typescript@5.8.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/promises': 3.0.3(typescript@5.8.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.8.3) + '@solana/subscribable': 3.0.3(typescript@5.8.3) + typescript: 5.8.3 + + '@solana/rpc-subscriptions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/errors': 2.3.0(typescript@5.8.3) + '@solana/fast-stable-stringify': 2.3.0(typescript@5.8.3) + '@solana/functional': 2.3.0(typescript@5.8.3) + '@solana/promises': 2.3.0(typescript@5.8.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.8.3) + '@solana/rpc-subscriptions-api': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc-subscriptions-channel-websocket': 2.3.0(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.8.3) + '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/subscribable': 2.3.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + '@solana/rpc-subscriptions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana/errors': 2.3.0(typescript@5.8.3) @@ -8894,6 +10165,42 @@ snapshots: - fastestsmallesttextencoderdecoder - ws + '@solana/rpc-subscriptions@3.0.3(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': 3.0.3(typescript@5.8.3) + '@solana/fast-stable-stringify': 3.0.3(typescript@5.8.3) + '@solana/functional': 3.0.3(typescript@5.8.3) + '@solana/promises': 3.0.3(typescript@5.8.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.8.3) + '@solana/rpc-subscriptions-api': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc-subscriptions-channel-websocket': 3.0.3(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-subscriptions-spec': 3.0.3(typescript@5.8.3) + '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/subscribable': 3.0.3(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + + '@solana/rpc-subscriptions@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/fast-stable-stringify': 3.0.3(typescript@5.8.3) + '@solana/functional': 3.0.3(typescript@5.8.3) + '@solana/promises': 3.0.3(typescript@5.8.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.8.3) + '@solana/rpc-subscriptions-api': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc-subscriptions-channel-websocket': 3.0.3(typescript@5.8.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-subscriptions-spec': 3.0.3(typescript@5.8.3) + '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/subscribable': 3.0.3(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + '@solana/rpc-transformers@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: '@solana/errors': 2.3.0(typescript@5.8.3) @@ -8905,6 +10212,17 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder + '@solana/rpc-transformers@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/functional': 3.0.3(typescript@5.8.3) + '@solana/nominal-types': 3.0.3(typescript@5.8.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.8.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + '@solana/rpc-transport-http@2.3.0(typescript@5.8.3)': dependencies: '@solana/errors': 2.3.0(typescript@5.8.3) @@ -8913,6 +10231,14 @@ snapshots: typescript: 5.8.3 undici-types: 7.16.0 + '@solana/rpc-transport-http@3.0.3(typescript@5.8.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/rpc-spec': 3.0.3(typescript@5.8.3) + '@solana/rpc-spec-types': 3.0.3(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.8.3)': dependencies: '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) @@ -8925,6 +10251,18 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder + '@solana/rpc-types@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/codecs-core': 3.0.3(typescript@5.8.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.8.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/nominal-types': 3.0.3(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + '@solana/rpc@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: '@solana/errors': 2.3.0(typescript@5.8.3) @@ -8940,6 +10278,21 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder + '@solana/rpc@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/fast-stable-stringify': 3.0.3(typescript@5.8.3) + '@solana/functional': 3.0.3(typescript@5.8.3) + '@solana/rpc-api': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc-spec': 3.0.3(typescript@5.8.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.8.3) + '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc-transport-http': 3.0.3(typescript@5.8.3) + '@solana/rpc-types': 3.0.3(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.8.3)': dependencies: '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) @@ -8954,51 +10307,66 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@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/signers@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@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) + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/codecs-core': 3.0.3(typescript@5.8.3) + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/instructions': 3.0.3(typescript@5.8.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/nominal-types': 3.0.3(typescript@5.8.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - - typescript - '@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/subscribable@2.3.0(typescript@5.8.3)': dependencies: - '@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/errors': 2.3.0(typescript@5.8.3) + typescript: 5.8.3 - '@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/subscribable@3.0.3(typescript@5.8.3)': dependencies: - '@solana/buffer-layout': 4.0.1 - '@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 + '@solana/errors': 3.0.3(typescript@5.8.3) + typescript: 5.8.3 + + '@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.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: - - bufferutil - - encoding - fastestsmallesttextencoderdecoder - - typescript - - utf-8-validate - '@solana/subscribable@2.3.0(typescript@5.8.3)': + '@solana/sysvars@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: - '@solana/errors': 2.3.0(typescript@5.8.3) + '@solana/accounts': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/codecs': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) typescript: 5.8.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder - '@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))': dependencies: - '@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/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) '@solana/errors': 2.3.0(typescript@5.8.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/promises': 2.3.0(typescript@5.8.3) + '@solana/rpc': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) typescript: 5.8.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder + - ws '@solana/transaction-confirmation@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: @@ -9034,6 +10402,40 @@ snapshots: - fastestsmallesttextencoderdecoder - ws + '@solana/transaction-confirmation@3.0.3(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': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/promises': 3.0.3(typescript@5.8.3) + '@solana/rpc': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc-subscriptions': 3.0.3(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': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + + '@solana/transaction-confirmation@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/promises': 3.0.3(typescript@5.8.3) + '@solana/rpc': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/rpc-subscriptions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/transactions': 3.0.3(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.8.3)': dependencies: '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) @@ -9049,6 +10451,21 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder + '@solana/transaction-messages@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/codecs-core': 3.0.3(typescript@5.8.3) + '@solana/codecs-data-structures': 3.0.3(typescript@5.8.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.8.3) + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/functional': 3.0.3(typescript@5.8.3) + '@solana/instructions': 3.0.3(typescript@5.8.3) + '@solana/nominal-types': 3.0.3(typescript@5.8.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + '@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) @@ -9067,13 +10484,31 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/web3.js@1.98.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': + '@solana/transactions@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/codecs-core': 3.0.3(typescript@5.8.3) + '@solana/codecs-data-structures': 3.0.3(typescript@5.8.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.8.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/errors': 3.0.3(typescript@5.8.3) + '@solana/functional': 3.0.3(typescript@5.8.3) + '@solana/instructions': 3.0.3(typescript@5.8.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/nominal-types': 3.0.3(typescript@5.8.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) + '@solana/transaction-messages': 3.0.3(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.8.3)(utf-8-validate@5.0.10)': dependencies: - '@babel/runtime': 7.27.6 - '@noble/curves': 1.9.2 + '@babel/runtime': 7.28.4 + '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 '@solana/buffer-layout': 4.0.1 - '@solana/codecs-numbers': 2.1.1(typescript@5.8.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.8.3) agentkeepalive: 4.6.0 bn.js: 5.2.2 borsh: 0.7.0 @@ -9082,7 +10517,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.1 + rpc-websockets: 9.2.0 superstruct: 2.0.2 transitivePeerDependencies: - bufferutil @@ -9090,54 +10525,54 @@ snapshots: - typescript - utf-8-validate - '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.28.0)': + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 - '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.28.0)': + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 - '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.28.0)': + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 - '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.28.0)': + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 - '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.28.0)': + '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 - '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.28.0)': + '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 - '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.28.0)': + '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 - '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.28.0)': + '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 - '@svgr/babel-preset@8.1.0(@babel/core@7.28.0)': + '@svgr/babel-preset@8.1.0(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 - '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.28.0) - '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.28.0) - '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.28.0) - '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.28.0) - '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.28.0) - '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.28.0) - '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.28.0) - '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.28.0) + '@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.8.3)': dependencies: - '@babel/core': 7.28.0 - '@svgr/babel-preset': 8.1.0(@babel/core@7.28.0) + '@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.8.3) snake-case: 3.0.4 @@ -9147,13 +10582,13 @@ snapshots: '@svgr/hast-util-to-babel-ast@8.0.0': dependencies: - '@babel/types': 7.28.0 + '@babel/types': 7.28.4 entities: 4.5.0 '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.8.3))': dependencies: - '@babel/core': 7.28.0 - '@svgr/babel-preset': 8.1.0(@babel/core@7.28.0) + '@babel/core': 7.28.4 + '@svgr/babel-preset': 8.1.0(@babel/core@7.28.4) '@svgr/core': 8.1.0(typescript@5.8.3) '@svgr/hast-util-to-babel-ast': 8.0.0 svg-parser: 2.0.4 @@ -9171,11 +10606,11 @@ snapshots: '@svgr/webpack@8.1.0(typescript@5.8.3)': dependencies: - '@babel/core': 7.28.0 - '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.28.0) - '@babel/preset-env': 7.28.0(@babel/core@7.28.0) - '@babel/preset-react': 7.27.1(@babel/core@7.28.0) - '@babel/preset-typescript': 7.27.1(@babel/core@7.28.0) + '@babel/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.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) @@ -9183,8 +10618,6 @@ snapshots: - supports-color - typescript - '@swc/counter@0.1.3': {} - '@swc/helpers@0.5.15': dependencies: tslib: 2.8.1 @@ -9193,28 +10626,16 @@ snapshots: dependencies: tslib: 2.8.1 - '@tanstack/query-core@5.81.5': {} + '@tanstack/query-core@5.90.5': {} - '@tanstack/react-query@5.81.5(react@19.1.0)': + '@tanstack/react-query@5.90.5(react@19.2.0)': dependencies: - '@tanstack/query-core': 5.81.5 - react: 19.1.0 + '@tanstack/query-core': 5.90.5 + react: 19.2.0 '@trysound/sax@0.2.0': {} - '@tsconfig/node10@1.0.11': - optional: true - - '@tsconfig/node12@1.0.11': - optional: true - - '@tsconfig/node14@1.0.3': - optional: true - - '@tsconfig/node16@1.0.4': - optional: true - - '@tybys/wasm-util@0.9.0': + '@tybys/wasm-util@0.10.1': dependencies: tslib: 2.8.1 optional: true @@ -9222,15 +10643,16 @@ snapshots: '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 20.19.4 + '@types/node': 22.16.0 - '@types/chai@5.2.2': + '@types/chai@5.2.3': dependencies: '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 '@types/connect@3.4.38': dependencies: - '@types/node': 20.19.4 + '@types/node': 22.16.0 '@types/debug@4.1.12': dependencies: @@ -9242,14 +10664,14 @@ snapshots: '@types/express-serve-static-core@4.19.6': dependencies: - '@types/node': 20.19.4 + '@types/node': 22.16.0 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 0.17.5 - '@types/express-serve-static-core@5.0.6': + '@types/express-serve-static-core@5.1.0': dependencies: - '@types/node': 20.19.4 + '@types/node': 22.16.0 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 0.17.5 @@ -9264,7 +10686,7 @@ snapshots: '@types/express@5.0.3': dependencies: '@types/body-parser': 1.19.6 - '@types/express-serve-static-core': 5.0.6 + '@types/express-serve-static-core': 5.1.0 '@types/serve-static': 1.15.8 '@types/http-errors@2.0.5': {} @@ -9273,6 +10695,8 @@ snapshots: '@types/json5@0.0.29': {} + '@types/lodash@4.17.20': {} + '@types/mime@1.3.5': {} '@types/ms@2.1.0': {} @@ -9291,23 +10715,23 @@ snapshots: '@types/range-parser@1.2.7': {} - '@types/react-dom@19.1.6(@types/react@19.1.8)': + '@types/react-dom@19.2.2(@types/react@19.2.2)': dependencies: - '@types/react': 19.1.8 + '@types/react': 19.2.2 - '@types/react@19.1.8': + '@types/react@19.2.2': dependencies: csstype: 3.1.3 '@types/send@0.17.5': dependencies: '@types/mime': 1.3.5 - '@types/node': 20.19.4 + '@types/node': 22.16.0 '@types/serve-static@1.15.8': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 20.19.4 + '@types/node': 22.16.0 '@types/send': 0.17.5 '@types/trusted-types@2.0.7': {} @@ -9316,21 +10740,21 @@ snapshots: '@types/ws@7.4.7': dependencies: - '@types/node': 20.19.4 + '@types/node': 22.16.0 '@types/ws@8.18.1': dependencies: - '@types/node': 20.19.4 + '@types/node': 22.16.0 - '@typescript-eslint/eslint-plugin@8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3)': + '@typescript-eslint/eslint-plugin@8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3)': dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) - '@typescript-eslint/scope-manager': 8.35.1 - '@typescript-eslint/type-utils': 8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) - '@typescript-eslint/utils': 8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.35.1 - eslint: 9.30.1(jiti@1.21.7) + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.46.2 + '@typescript-eslint/type-utils': 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/utils': 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.46.2 + eslint: 9.38.0(jiti@1.21.7) graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 @@ -9339,155 +10763,156 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3)': + '@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3)': dependencies: - '@typescript-eslint/scope-manager': 8.35.1 - '@typescript-eslint/types': 8.35.1 - '@typescript-eslint/typescript-estree': 8.35.1(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.35.1 - debug: 4.4.1 - eslint: 9.30.1(jiti@1.21.7) + '@typescript-eslint/scope-manager': 8.46.2 + '@typescript-eslint/types': 8.46.2 + '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.46.2 + debug: 4.4.3 + eslint: 9.38.0(jiti@1.21.7) typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.35.1(typescript@5.8.3)': + '@typescript-eslint/project-service@8.46.2(typescript@5.8.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.35.1(typescript@5.8.3) - '@typescript-eslint/types': 8.35.1 - debug: 4.4.1 + '@typescript-eslint/tsconfig-utils': 8.46.2(typescript@5.8.3) + '@typescript-eslint/types': 8.46.2 + debug: 4.4.3 typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.35.1': + '@typescript-eslint/scope-manager@8.46.2': dependencies: - '@typescript-eslint/types': 8.35.1 - '@typescript-eslint/visitor-keys': 8.35.1 + '@typescript-eslint/types': 8.46.2 + '@typescript-eslint/visitor-keys': 8.46.2 - '@typescript-eslint/tsconfig-utils@8.35.1(typescript@5.8.3)': + '@typescript-eslint/tsconfig-utils@8.46.2(typescript@5.8.3)': dependencies: typescript: 5.8.3 - '@typescript-eslint/type-utils@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3)': + '@typescript-eslint/type-utils@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.35.1(typescript@5.8.3) - '@typescript-eslint/utils': 8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) - debug: 4.4.1 - eslint: 9.30.1(jiti@1.21.7) + '@typescript-eslint/types': 8.46.2 + '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.8.3) + '@typescript-eslint/utils': 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + debug: 4.4.3 + eslint: 9.38.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.35.1': {} + '@typescript-eslint/types@8.46.2': {} - '@typescript-eslint/typescript-estree@8.35.1(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@8.46.2(typescript@5.8.3)': dependencies: - '@typescript-eslint/project-service': 8.35.1(typescript@5.8.3) - '@typescript-eslint/tsconfig-utils': 8.35.1(typescript@5.8.3) - '@typescript-eslint/types': 8.35.1 - '@typescript-eslint/visitor-keys': 8.35.1 - debug: 4.4.1 + '@typescript-eslint/project-service': 8.46.2(typescript@5.8.3) + '@typescript-eslint/tsconfig-utils': 8.46.2(typescript@5.8.3) + '@typescript-eslint/types': 8.46.2 + '@typescript-eslint/visitor-keys': 8.46.2 + debug: 4.4.3 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.2 + semver: 7.7.3 ts-api-utils: 2.1.0(typescript@5.8.3) typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3)': + '@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@1.21.7)) - '@typescript-eslint/scope-manager': 8.35.1 - '@typescript-eslint/types': 8.35.1 - '@typescript-eslint/typescript-estree': 8.35.1(typescript@5.8.3) - eslint: 9.30.1(jiti@1.21.7) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.38.0(jiti@1.21.7)) + '@typescript-eslint/scope-manager': 8.46.2 + '@typescript-eslint/types': 8.46.2 + '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.8.3) + eslint: 9.38.0(jiti@1.21.7) typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.35.1': + '@typescript-eslint/visitor-keys@8.46.2': dependencies: - '@typescript-eslint/types': 8.35.1 + '@typescript-eslint/types': 8.46.2 eslint-visitor-keys: 4.2.1 - '@unrs/resolver-binding-android-arm-eabi@1.10.1': + '@unrs/resolver-binding-android-arm-eabi@1.11.1': optional: true - '@unrs/resolver-binding-android-arm64@1.10.1': + '@unrs/resolver-binding-android-arm64@1.11.1': optional: true - '@unrs/resolver-binding-darwin-arm64@1.10.1': + '@unrs/resolver-binding-darwin-arm64@1.11.1': optional: true - '@unrs/resolver-binding-darwin-x64@1.10.1': + '@unrs/resolver-binding-darwin-x64@1.11.1': optional: true - '@unrs/resolver-binding-freebsd-x64@1.10.1': + '@unrs/resolver-binding-freebsd-x64@1.11.1': optional: true - '@unrs/resolver-binding-linux-arm-gnueabihf@1.10.1': + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': optional: true - '@unrs/resolver-binding-linux-arm-musleabihf@1.10.1': + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': optional: true - '@unrs/resolver-binding-linux-arm64-gnu@1.10.1': + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': optional: true - '@unrs/resolver-binding-linux-arm64-musl@1.10.1': + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': optional: true - '@unrs/resolver-binding-linux-ppc64-gnu@1.10.1': + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': optional: true - '@unrs/resolver-binding-linux-riscv64-gnu@1.10.1': + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': optional: true - '@unrs/resolver-binding-linux-riscv64-musl@1.10.1': + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': optional: true - '@unrs/resolver-binding-linux-s390x-gnu@1.10.1': + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': optional: true - '@unrs/resolver-binding-linux-x64-gnu@1.10.1': + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': optional: true - '@unrs/resolver-binding-linux-x64-musl@1.10.1': + '@unrs/resolver-binding-linux-x64-musl@1.11.1': optional: true - '@unrs/resolver-binding-wasm32-wasi@1.10.1': + '@unrs/resolver-binding-wasm32-wasi@1.11.1': dependencies: - '@napi-rs/wasm-runtime': 0.2.11 + '@napi-rs/wasm-runtime': 0.2.12 optional: true - '@unrs/resolver-binding-win32-arm64-msvc@1.10.1': + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': optional: true - '@unrs/resolver-binding-win32-ia32-msvc@1.10.1': + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': optional: true - '@unrs/resolver-binding-win32-x64-msvc@1.10.1': + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': optional: true '@vitest/expect@3.2.4': dependencies: - '@types/chai': 5.2.2 + '@types/chai': 5.2.3 '@vitest/spy': 3.2.4 '@vitest/utils': 3.2.4 - chai: 5.2.0 + chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@6.3.5(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0))': + '@vitest/mocker@3.2.4(vite@6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(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.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) '@vitest/pretty-format@3.2.4': dependencies: @@ -9497,33 +10922,83 @@ snapshots: dependencies: '@vitest/utils': 3.2.4 pathe: 2.0.3 - strip-literal: 3.0.0 + strip-literal: 3.1.0 '@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.1.4 + loupe: 3.2.1 tinyrainbow: 2.0.0 - '@wagmi/connectors@5.8.5(@types/react@19.1.8)(@wagmi/core@2.17.3(@tanstack/query-core@5.81.5)(@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.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)))(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71)': + '@wagmi/connectors@5.11.2(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)))(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71))(zod@3.25.71)': + dependencies: + '@base-org/account': 1.1.1(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@3.25.71) + '@coinbase/wallet-sdk': 4.3.6(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@3.25.71) + '@gemini-wallet/core': 0.2.0(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)) + '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@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.71) + '@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.71) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + cbw-sdk: '@coinbase/wallet-sdk@3.9.3' + porto: 0.2.19(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)))(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71)) + viem: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + optionalDependencies: + typescript: 5.8.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' + - '@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@6.1.0(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)))(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71))(zod@3.25.71)': dependencies: - '@coinbase/wallet-sdk': 4.3.3 - '@metamask/sdk': 0.32.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@base-org/account': 1.1.1(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@3.25.71) + '@coinbase/wallet-sdk': 4.3.6(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@3.25.71) + '@gemini-wallet/core': 0.2.0(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)) + '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@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.71) '@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.71) - '@wagmi/core': 2.17.3(@tanstack/query-core@5.81.5)(@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.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)) - '@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.71) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) cbw-sdk: '@coinbase/wallet-sdk@3.9.3' + porto: 0.2.19(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)))(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71)) viem: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) optionalDependencies: typescript: 5.8.3 @@ -9539,29 +11014,96 @@ 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 + - db0 + - encoding + - immer + - ioredis + - react + - supports-color + - uploadthing + - use-sync-external-store + - utf-8-validate + - wagmi + - zod + + '@wagmi/connectors@6.1.0(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)))(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71))(zod@3.25.71)': + dependencies: + '@base-org/account': 1.1.1(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@3.25.71) + '@coinbase/wallet-sdk': 4.3.6(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@3.25.71) + '@gemini-wallet/core': 0.2.0(viem@2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)) + '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@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.71) + '@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.71) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + cbw-sdk: '@coinbase/wallet-sdk@3.9.3' + porto: 0.2.19(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)))(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71)) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + optionalDependencies: + typescript: 5.8.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' + - '@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/core@2.17.3(@tanstack/query-core@5.81.5)(@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.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))': + '@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))': dependencies: eventemitter3: 5.0.1 mipd: 0.0.7(typescript@5.8.3) viem: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) - zustand: 5.0.0(@types/react@19.1.8)(react@19.1.0)(use-sync-external-store@1.4.0(react@19.1.0)) + zustand: 5.0.0(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)) + optionalDependencies: + '@tanstack/query-core': 5.90.5 + typescript: 5.8.3 + transitivePeerDependencies: + - '@types/react' + - immer + - react + - use-sync-external-store + + '@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))': + dependencies: + eventemitter3: 5.0.1 + mipd: 0.0.7(typescript@5.8.3) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + zustand: 5.0.0(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)) optionalDependencies: - '@tanstack/query-core': 5.81.5 + '@tanstack/query-core': 5.90.5 typescript: 5.8.3 transitivePeerDependencies: - '@types/react' @@ -9602,6 +11144,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -9645,6 +11188,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -9659,9 +11203,9 @@ snapshots: dependencies: tslib: 1.14.1 - '@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.71)': + '@walletconnect/ethereum-provider@2.21.1(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)': dependencies: - '@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.71) + '@reown/appkit': 1.7.8(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) '@walletconnect/jsonrpc-http-connection': 1.0.8 '@walletconnect/jsonrpc-provider': 1.0.14 '@walletconnect/jsonrpc-types': 1.0.4 @@ -9687,6 +11231,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -9750,7 +11295,7 @@ snapshots: dependencies: '@walletconnect/safe-json': 1.0.2 idb-keyval: 6.2.2 - unstorage: 1.16.0(idb-keyval@6.2.2) + unstorage: 1.17.1(idb-keyval@6.2.2) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -9764,6 +11309,7 @@ snapshots: - '@planetscale/database' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - db0 @@ -9816,6 +11362,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -9851,6 +11398,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -9887,6 +11435,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - db0 @@ -9915,6 +11464,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - db0 @@ -9949,6 +11499,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -9988,6 +11539,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -10032,6 +11584,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -10075,6 +11628,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -10099,16 +11653,41 @@ snapshots: typescript: 5.8.3 zod: 3.25.71 - abitype@1.0.8(typescript@5.8.3)(zod@3.22.4): + abitype@1.0.8(typescript@5.8.3)(zod@3.25.71): + optionalDependencies: + typescript: 5.8.3 + zod: 3.25.71 + + abitype@1.1.0(typescript@5.8.3)(zod@3.22.4): optionalDependencies: typescript: 5.8.3 zod: 3.22.4 - abitype@1.0.8(typescript@5.8.3)(zod@3.25.71): + abitype@1.1.0(typescript@5.8.3)(zod@3.25.71): + optionalDependencies: + typescript: 5.8.3 + zod: 3.25.71 + + abitype@1.1.0(typescript@5.8.3)(zod@4.1.12): + optionalDependencies: + typescript: 5.8.3 + zod: 4.1.12 + + abitype@1.1.1(typescript@5.8.3)(zod@3.22.4): + optionalDependencies: + typescript: 5.8.3 + zod: 3.22.4 + + abitype@1.1.1(typescript@5.8.3)(zod@3.25.71): optionalDependencies: typescript: 5.8.3 zod: 3.25.71 + abitype@1.1.1(typescript@5.8.3)(zod@4.1.12): + optionalDependencies: + typescript: 5.8.3 + zod: 4.1.12 + accepts@1.3.8: dependencies: mime-types: 2.1.35 @@ -10118,14 +11697,9 @@ snapshots: dependencies: acorn: 8.15.0 - acorn-walk@8.3.4: - dependencies: - acorn: 8.15.0 - optional: true - acorn@8.15.0: {} - agent-base@7.1.3: {} + agent-base@7.1.4: {} agentkeepalive@4.6.0: dependencies: @@ -10138,15 +11712,22 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + 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.1.0: {} + ansi-regex@6.2.2: {} ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 - ansi-styles@6.2.1: {} + ansi-styles@6.2.3: {} any-promise@1.3.0: {} @@ -10157,9 +11738,6 @@ snapshots: are-docs-informative@0.0.2: {} - arg@4.1.3: - optional: true - arg@5.0.2: {} argparse@2.0.1: {} @@ -10261,11 +11839,11 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 - axe-core@4.10.3: {} + axe-core@4.11.0: {} - axios-retry@4.5.0(axios@1.10.0): + axios-retry@4.5.0(axios@1.12.2): dependencies: - axios: 1.10.0 + axios: 1.12.2 is-retry-allowed: 2.2.0 axios@1.10.0: @@ -10276,29 +11854,37 @@ snapshots: transitivePeerDependencies: - debug + axios@1.12.2: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.4 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + axobject-query@4.1.0: {} - babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.0): + babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.4): dependencies: - '@babel/compat-data': 7.28.0 - '@babel/core': 7.28.0 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.0) + '@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.0): + babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.28.4): dependencies: - '@babel/core': 7.28.0 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.0) - core-js-compat: 3.43.0 + '@babel/core': 7.28.4 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.4) + core-js-compat: 3.46.0 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.28.0): + babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.28.4): dependencies: - '@babel/core': 7.28.0 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.0) + '@babel/core': 7.28.4 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.4) transitivePeerDependencies: - supports-color @@ -10312,20 +11898,12 @@ snapshots: base64-js@1.5.1: {} - big.js@6.2.2: {} - - bigint-buffer@1.1.5: - dependencies: - bindings: 1.5.0 + baseline-browser-mapping@2.8.19: {} - bignumber.js@9.3.0: {} + big.js@6.2.2: {} binary-extensions@2.3.0: {} - bindings@1.5.0: - dependencies: - file-uri-to-path: 1.0.0 - bn.js@4.12.2: {} bn.js@5.2.2: {} @@ -10355,7 +11933,7 @@ snapshots: bs58: 4.0.1 text-encoding-utf-8: 1.0.2 - bowser@2.11.0: {} + bowser@2.12.1: {} brace-expansion@1.1.12: dependencies: @@ -10375,7 +11953,7 @@ snapshots: browserify-aes@1.2.0: dependencies: buffer-xor: 1.0.3 - cipher-base: 1.0.6 + cipher-base: 1.0.7 create-hash: 1.2.0 evp_bytestokey: 1.0.3 inherits: 2.0.4 @@ -10389,7 +11967,7 @@ snapshots: browserify-des@1.0.2: dependencies: - cipher-base: 1.0.6 + cipher-base: 1.0.7 des.js: 1.1.0 inherits: 2.0.4 safe-buffer: 5.2.1 @@ -10400,25 +11978,25 @@ snapshots: randombytes: 2.1.0 safe-buffer: 5.2.1 - browserify-sign@4.2.3: + browserify-sign@4.2.5: dependencies: bn.js: 5.2.2 browserify-rsa: 4.1.1 create-hash: 1.2.0 create-hmac: 1.1.7 elliptic: 6.6.1 - hash-base: 3.0.5 inherits: 2.0.4 - parse-asn1: 5.1.7 + parse-asn1: 5.1.9 readable-stream: 2.3.8 safe-buffer: 5.2.1 - browserslist@4.25.1: + browserslist@4.27.0: dependencies: - caniuse-lite: 1.0.30001726 - electron-to-chromium: 1.5.179 - node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.25.1) + baseline-browser-mapping: 2.8.19 + caniuse-lite: 1.0.30001751 + electron-to-chromium: 1.5.239 + node-releases: 2.0.26 + update-browserslist-db: 1.1.4(browserslist@4.27.0) bs58@4.0.1: dependencies: @@ -10449,10 +12027,6 @@ snapshots: 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: {} @@ -10482,14 +12056,14 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001726: {} + caniuse-lite@1.0.30001751: {} - chai@5.2.0: + chai@5.3.3: dependencies: assertion-error: 2.0.1 check-error: 2.1.1 deep-eql: 5.0.2 - loupe: 3.1.4 + loupe: 3.2.1 pathval: 2.0.1 chalk@4.1.2: @@ -10497,7 +12071,7 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 - chalk@5.4.1: {} + chalk@5.6.2: {} charenc@0.0.2: {} @@ -10519,10 +12093,11 @@ snapshots: dependencies: readdirp: 4.1.2 - 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 client-only@0.0.1: {} @@ -10542,27 +12117,13 @@ snapshots: color-name@1.1.4: {} - color-string@1.9.1: - dependencies: - color-name: 1.1.4 - simple-swizzle: 0.2.2 - optional: true - - color@4.2.3: - dependencies: - color-convert: 2.0.1 - color-string: 1.9.1 - optional: true - combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 comlink@4.4.2: {} - commander@12.1.0: {} - - commander@13.1.0: {} + commander@14.0.0: {} commander@14.0.1: {} @@ -10594,9 +12155,9 @@ snapshots: cookie@0.7.1: {} - core-js-compat@3.43.0: + core-js-compat@3.46.0: dependencies: - browserslist: 4.25.1 + browserslist: 4.27.0 core-util-is@1.0.3: {} @@ -10616,33 +12177,23 @@ snapshots: bn.js: 4.12.2 elliptic: 6.6.1 - create-hash@1.1.3: - dependencies: - cipher-base: 1.0.6 - inherits: 2.0.4 - ripemd160: 2.0.1 - sha.js: 2.4.12 - 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 create-hmac@1.1.7: dependencies: - cipher-base: 1.0.6 + cipher-base: 1.0.7 create-hash: 1.2.0 inherits: 2.0.4 - ripemd160: 2.0.2 + ripemd160: 2.0.3 safe-buffer: 5.2.1 sha.js: 2.4.12 - create-require@1.1.1: - optional: true - cross-fetch@3.2.0: dependencies: node-fetch: 2.7.0 @@ -10670,14 +12221,14 @@ snapshots: crypto-browserify@3.12.1: dependencies: browserify-cipher: 1.0.1 - browserify-sign: 4.2.3 + browserify-sign: 4.2.5 create-ecdh: 4.0.4 create-hash: 1.2.0 create-hmac: 1.1.7 diffie-hellman: 5.0.3 hash-base: 3.0.5 inherits: 2.0.4 - pbkdf2: 3.1.3 + pbkdf2: 3.1.5 public-encrypt: 4.0.3 randombytes: 2.1.0 randomfill: 1.0.4 @@ -10742,7 +12293,7 @@ snapshots: date-fns@2.30.0: dependencies: - '@babel/runtime': 7.27.6 + '@babel/runtime': 7.28.4 dayjs@1.11.13: {} @@ -10754,17 +12305,17 @@ 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 decamelize@1.2.0: {} - decimal.js@10.5.0: {} + decimal.js@10.6.0: {} decode-uri-component@0.2.2: {} @@ -10794,9 +12345,9 @@ snapshots: depd@2.0.0: {} - derive-valtio@0.1.0(valtio@1.13.2(@types/react@19.1.8)(react@19.1.0)): + derive-valtio@0.1.0(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0)): dependencies: - valtio: 1.13.2(@types/react@19.1.8)(react@19.1.0) + valtio: 1.13.2(@types/react@19.2.2)(react@19.2.0) des.js@1.1.0: dependencies: @@ -10809,14 +12360,11 @@ snapshots: detect-browser@5.3.0: {} - detect-libc@2.0.4: + detect-libc@2.1.2: optional: true didyoumean@1.2.2: {} - diff@4.0.2: - optional: true - diffie-hellman@5.0.3: dependencies: bn.js: 4.12.2 @@ -10877,16 +12425,16 @@ snapshots: eastasianwidth@0.2.0: {} - eciesjs@0.4.15: + eciesjs@0.4.16: dependencies: - '@ecies/ciphers': 0.2.3(@noble/ciphers@1.3.0) + '@ecies/ciphers': 0.2.4(@noble/ciphers@1.3.0) '@noble/ciphers': 1.3.0 - '@noble/curves': 1.9.2 + '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 ee-first@1.1.1: {} - electron-to-chromium@1.5.179: {} + electron-to-chromium@1.5.239: {} elliptic@6.6.1: dependencies: @@ -10915,7 +12463,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 @@ -10930,7 +12478,7 @@ snapshots: entities@6.0.1: {} - error-ex@1.3.2: + error-ex@1.3.4: dependencies: is-arrayish: 0.2.1 @@ -11105,19 +12653,19 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-next@15.1.7(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3): + eslint-config-next@15.1.7(eslint@9.38.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.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) - '@typescript-eslint/parser': 8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) - eslint: 9.30.1(jiti@1.21.7) + '@rushstack/eslint-patch': 1.14.0 + '@typescript-eslint/eslint-plugin': 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/parser': 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + eslint: 9.38.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.30.1(jiti@1.21.7)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@1.21.7)) - eslint-plugin-jsx-a11y: 6.10.2(eslint@9.30.1(jiti@1.21.7)) - eslint-plugin-react: 7.37.5(eslint@9.30.1(jiti@1.21.7)) - eslint-plugin-react-hooks: 5.2.0(eslint@9.30.1(jiti@1.21.7)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-react: 7.37.5(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-react-hooks: 5.2.0(eslint@9.38.0(jiti@1.21.7)) optionalDependencies: typescript: 5.8.3 transitivePeerDependencies: @@ -11129,37 +12677,37 @@ snapshots: dependencies: debug: 3.2.7 is-core-module: 2.16.1 - resolve: 1.22.10 + resolve: 1.22.11 transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.30.1(jiti@1.21.7)): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.38.0(jiti@1.21.7)): dependencies: '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.1 - eslint: 9.30.1(jiti@1.21.7) + debug: 4.4.3 + eslint: 9.38.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.10.1 + tinyglobby: 0.2.15 + unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@1.21.7)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@1.21.7)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.46.2(eslint@9.38.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.38.0(jiti@1.21.7)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) - eslint: 9.30.1(jiti@1.21.7) + '@typescript-eslint/parser': 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3) + eslint: 9.38.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.30.1(jiti@1.21.7)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.38.0(jiti@1.21.7)) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@1.21.7)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -11168,9 +12716,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 - eslint: 9.30.1(jiti@1.21.7) + eslint: 9.38.0(jiti@1.21.7) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.30.1(jiti@1.21.7)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.46.2(eslint@9.38.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.38.0(jiti@1.21.7)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -11182,39 +12730,39 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.35.1(eslint@9.30.1(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/parser': 8.46.2(eslint@9.38.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.30.1(jiti@1.21.7)): + eslint-plugin-jsdoc@50.8.0(eslint@9.38.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.30.1(jiti@1.21.7) + eslint: 9.38.0(jiti@1.21.7) espree: 10.4.0 esquery: 1.6.0 parse-imports-exports: 0.2.4 - semver: 7.7.2 + semver: 7.7.3 spdx-expression-parse: 4.0.0 transitivePeerDependencies: - supports-color - eslint-plugin-jsx-a11y@6.10.2(eslint@9.30.1(jiti@1.21.7)): + eslint-plugin-jsx-a11y@6.10.2(eslint@9.38.0(jiti@1.21.7)): dependencies: aria-query: 5.3.2 array-includes: 3.1.9 array.prototype.flatmap: 1.3.3 ast-types-flow: 0.0.8 - axe-core: 4.10.3 + axe-core: 4.11.0 axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 9.30.1(jiti@1.21.7) + eslint: 9.38.0(jiti@1.21.7) hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -11223,18 +12771,18 @@ snapshots: safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 - eslint-plugin-prettier@5.5.1(eslint@9.30.1(jiti@1.21.7))(prettier@3.5.2): + eslint-plugin-prettier@5.5.4(eslint@9.38.0(jiti@1.21.7))(prettier@3.5.2): dependencies: - eslint: 9.30.1(jiti@1.21.7) + eslint: 9.38.0(jiti@1.21.7) prettier: 3.5.2 prettier-linter-helpers: 1.0.0 - synckit: 0.11.8 + synckit: 0.11.11 - eslint-plugin-react-hooks@5.2.0(eslint@9.30.1(jiti@1.21.7)): + eslint-plugin-react-hooks@5.2.0(eslint@9.38.0(jiti@1.21.7)): dependencies: - eslint: 9.30.1(jiti@1.21.7) + eslint: 9.38.0(jiti@1.21.7) - eslint-plugin-react@7.37.5(eslint@9.30.1(jiti@1.21.7)): + eslint-plugin-react@7.37.5(eslint@9.38.0(jiti@1.21.7)): dependencies: array-includes: 3.1.9 array.prototype.findlast: 1.2.5 @@ -11242,7 +12790,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.2.1 - eslint: 9.30.1(jiti@1.21.7) + eslint: 9.38.0(jiti@1.21.7) estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -11265,25 +12813,24 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.30.1(jiti@1.21.7): + eslint@9.38.0(jiti@1.21.7): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@1.21.7)) - '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.21.0 - '@eslint/config-helpers': 0.3.0 - '@eslint/core': 0.14.0 + '@eslint-community/eslint-utils': 4.9.0(eslint@9.38.0(jiti@1.21.7)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.1 + '@eslint/config-helpers': 0.4.1 + '@eslint/core': 0.16.0 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.30.1 - '@eslint/plugin-kit': 0.3.3 - '@humanfs/node': 0.16.6 + '@eslint/js': 9.38.0 + '@eslint/plugin-kit': 0.4.0 + '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 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 @@ -11388,7 +12935,7 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 - expect-type@1.2.1: {} + expect-type@1.2.2: {} express@4.21.2: dependencies: @@ -11463,22 +13010,22 @@ snapshots: fast-stable-stringify@1.0.0: {} + fast-uri@3.1.0: {} + fastestsmallesttextencoderdecoder@1.0.22: {} fastq@1.19.1: dependencies: reusify: 1.1.0 - fdir@6.4.6(picomatch@4.0.2): + fdir@6.5.0(picomatch@4.0.3): optionalDependencies: - picomatch: 4.0.2 + picomatch: 4.0.3 file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 - file-uri-to-path@1.0.0: {} - fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -11509,9 +13056,9 @@ snapshots: fix-dts-default-cjs-exports@1.0.1: dependencies: - magic-string: 0.30.17 - mlly: 1.7.4 - rollup: 4.44.1 + magic-string: 0.30.19 + mlly: 1.8.0 + rollup: 4.52.5 flat-cache@4.0.1: dependencies: @@ -11539,6 +13086,14 @@ snapshots: hasown: 2.0.2 mime-types: 2.1.35 + form-data@4.0.4: + 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 + forwarded@0.2.0: {} fresh@0.5.2: {} @@ -11559,6 +13114,8 @@ snapshots: functions-have-names@1.2.3: {} + generator-function@2.0.1: {} + gensync@1.0.0-beta.2: {} get-caller-file@2.0.5: {} @@ -11642,14 +13199,14 @@ snapshots: graphql@16.11.0: {} - h3@1.15.3: + h3@1.15.4: 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.1 + node-mock-http: 1.0.3 radix3: 1.1.2 ufo: 1.6.1 uncrypto: 0.1.3 @@ -11672,14 +13229,17 @@ snapshots: dependencies: has-symbols: 1.1.0 - hash-base@2.0.2: + hash-base@3.0.5: dependencies: inherits: 2.0.4 + safe-buffer: 5.2.1 - hash-base@3.0.5: + hash-base@3.1.2: dependencies: inherits: 2.0.4 + readable-stream: 2.3.8 safe-buffer: 5.2.1 + to-buffer: 1.2.2 hash.js@1.1.7: dependencies: @@ -11696,7 +13256,7 @@ snapshots: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 - hono@4.8.3: {} + hono@4.10.2: {} html-encoding-sniffer@4.0.0: dependencies: @@ -11712,15 +13272,15 @@ snapshots: http-proxy-agent@7.0.2: dependencies: - agent-base: 7.1.3 - debug: 4.4.1 + agent-base: 7.1.4 + debug: 4.4.3 transitivePeerDependencies: - supports-color https-proxy-agent@7.0.6: dependencies: - agent-base: 7.1.3 - debug: 4.4.1 + agent-base: 7.1.4 + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -11738,6 +13298,8 @@ snapshots: dependencies: safer-buffer: 2.1.2 + idb-keyval@6.2.1: {} + idb-keyval@6.2.2: {} ieee754@1.2.1: {} @@ -11778,9 +13340,6 @@ snapshots: is-arrayish@0.2.1: {} - is-arrayish@0.3.2: - optional: true - is-async-function@2.1.1: dependencies: async-function: 1.0.0 @@ -11806,7 +13365,7 @@ snapshots: is-bun-module@2.0.0: dependencies: - semver: 7.7.2 + semver: 7.7.3 is-callable@1.2.7: {} @@ -11833,9 +13392,10 @@ snapshots: is-fullwidth-code-point@3.0.0: {} - is-generator-function@1.1.0: + is-generator-function@1.1.2: dependencies: call-bound: 1.0.4 + generator-function: 2.0.1 get-proto: 1.0.1 has-tostringtag: 1.0.2 safe-regex-test: 1.1.0 @@ -11918,6 +13478,10 @@ snapshots: dependencies: ws: 8.18.2(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)): + dependencies: + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + iterator.prototype@1.1.5: dependencies: define-data-property: 1.1.4 @@ -11955,7 +13519,7 @@ snapshots: jose@5.10.0: {} - jose@6.0.11: {} + jose@6.1.0: {} joycon@3.1.1: {} @@ -11973,12 +13537,12 @@ snapshots: dependencies: cssstyle: 4.6.0 data-urls: 5.0.0 - decimal.js: 10.5.0 + decimal.js: 10.6.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.20 + nwsapi: 2.2.22 parse5: 7.3.0 rrweb-cssom: 0.8.0 saxes: 6.0.0 @@ -11996,8 +13560,6 @@ snapshots: - supports-color - utf-8-validate - jsesc@3.0.2: {} - jsesc@3.1.0: {} json-buffer@3.0.1: {} @@ -12013,6 +13575,8 @@ snapshots: json-schema-traverse@0.4.1: {} + json-schema-traverse@1.0.0: {} + json-stable-stringify-without-jsonify@1.0.1: {} json-stringify-safe@5.0.1: {} @@ -12057,21 +13621,21 @@ snapshots: lines-and-columns@1.2.4: {} - lit-element@4.2.0: + lit-element@4.2.1: dependencies: - '@lit-labs/ssr-dom-shim': 1.3.0 - '@lit/reactive-element': 2.1.0 - lit-html: 3.3.0 + '@lit-labs/ssr-dom-shim': 1.4.0 + '@lit/reactive-element': 2.1.1 + lit-html: 3.3.1 - lit-html@3.3.0: + lit-html@3.3.1: dependencies: '@types/trusted-types': 2.0.7 lit@3.3.0: dependencies: - '@lit/reactive-element': 2.1.0 - lit-element: 4.2.0 - lit-html: 3.3.0 + '@lit/reactive-element': 2.1.1 + lit-element: 4.2.1 + lit-html: 3.3.1 load-tsconfig@0.2.5: {} @@ -12095,7 +13659,7 @@ snapshots: dependencies: js-tokens: 4.0.0 - loupe@3.1.4: {} + loupe@3.2.1: {} lower-case@2.0.2: dependencies: @@ -12107,12 +13671,9 @@ snapshots: dependencies: yallist: 3.1.1 - magic-string@0.30.17: + magic-string@0.30.19: dependencies: - '@jridgewell/sourcemap-codec': 1.5.4 - - make-error@1.3.6: - optional: true + '@jridgewell/sourcemap-codec': 1.5.5 math-intrinsics@1.1.0: {} @@ -12184,7 +13745,7 @@ snapshots: optionalDependencies: typescript: 5.8.3 - mlly@1.7.4: + mlly@1.8.0: dependencies: acorn: 8.15.0 pathe: 2.0.3 @@ -12193,6 +13754,8 @@ snapshots: ms@2.0.0: {} + ms@2.1.2: {} + ms@2.1.3: {} multiformats@9.9.0: {} @@ -12205,56 +13768,31 @@ snapshots: nanoid@3.3.11: {} - napi-postinstall@0.3.0: {} + napi-postinstall@0.3.4: {} natural-compare@1.4.0: {} negotiator@0.6.3: {} - next@15.3.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0): - dependencies: - '@next/env': 15.3.4 - '@swc/counter': 0.1.3 - '@swc/helpers': 0.5.15 - busboy: 1.6.0 - caniuse-lite: 1.0.30001726 - postcss: 8.4.31 - react: 19.1.0 - react-dom: 19.1.0(react@19.1.0) - styled-jsx: 5.1.6(@babel/core@7.28.0)(react@19.1.0) - optionalDependencies: - '@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 - - next@15.4.0-canary.113(@babel/core@7.28.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + next@15.5.6(@babel/core@7.28.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: - '@next/env': 15.4.0-canary.113 + '@next/env': 15.5.6 '@swc/helpers': 0.5.15 - caniuse-lite: 1.0.30001726 + caniuse-lite: 1.0.30001751 postcss: 8.4.31 - react: 19.1.0 - react-dom: 19.1.0(react@19.1.0) - styled-jsx: 5.1.6(@babel/core@7.28.0)(react@19.1.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + styled-jsx: 5.1.6(@babel/core@7.28.4)(react@19.2.0) optionalDependencies: - '@next/swc-darwin-arm64': 15.4.0-canary.113 - '@next/swc-darwin-x64': 15.4.0-canary.113 - '@next/swc-linux-arm64-gnu': 15.4.0-canary.113 - '@next/swc-linux-arm64-musl': 15.4.0-canary.113 - '@next/swc-linux-x64-gnu': 15.4.0-canary.113 - '@next/swc-linux-x64-musl': 15.4.0-canary.113 - '@next/swc-win32-arm64-msvc': 15.4.0-canary.113 - '@next/swc-win32-x64-msvc': 15.4.0-canary.113 - sharp: 0.34.2 + '@next/swc-darwin-arm64': 15.5.6 + '@next/swc-darwin-x64': 15.5.6 + '@next/swc-linux-arm64-gnu': 15.5.6 + '@next/swc-linux-arm64-musl': 15.5.6 + '@next/swc-linux-x64-gnu': 15.5.6 + '@next/swc-linux-x64-musl': 15.5.6 + '@next/swc-win32-arm64-msvc': 15.5.6 + '@next/swc-win32-x64-msvc': 15.5.6 + sharp: 0.34.4 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -12266,7 +13804,7 @@ snapshots: node-addon-api@2.0.2: {} - node-fetch-native@1.6.6: {} + node-fetch-native@1.6.7: {} node-fetch@2.7.0: dependencies: @@ -12274,9 +13812,9 @@ snapshots: node-gyp-build@4.8.4: {} - node-mock-http@1.0.1: {} + node-mock-http@1.0.3: {} - node-releases@2.0.19: {} + node-releases@2.0.26: {} normalize-path@3.0.0: {} @@ -12288,7 +13826,7 @@ snapshots: dependencies: boolbase: 1.0.0 - nwsapi@2.2.20: {} + nwsapi@2.2.22: {} obj-multiplex@1.0.0: dependencies: @@ -12343,7 +13881,7 @@ snapshots: ofetch@1.4.1: dependencies: destr: 2.0.5 - node-fetch-native: 1.6.6 + node-fetch-native: 1.6.7 ufo: 1.6.1 on-exit-leak-free@0.2.0: {} @@ -12360,6 +13898,12 @@ snapshots: dependencies: mimic-fn: 2.1.0 + openapi-fetch@0.13.8: + dependencies: + openapi-typescript-helpers: 0.0.15 + + openapi-typescript-helpers@0.0.15: {} + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -12378,11 +13922,11 @@ snapshots: ox@0.4.4(typescript@5.8.3)(zod@3.25.71): dependencies: '@adraffy/ens-normalize': 1.11.0 - '@noble/curves': 1.9.2 + '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.0.8(typescript@5.8.3)(zod@3.25.71) + abitype: 1.1.1(typescript@5.8.3)(zod@3.25.71) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.8.3 @@ -12392,26 +13936,25 @@ snapshots: ox@0.6.7(typescript@5.8.3)(zod@3.25.71): dependencies: '@adraffy/ens-normalize': 1.11.0 - '@noble/curves': 1.9.2 + '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.0.8(typescript@5.8.3)(zod@3.25.71) + abitype: 1.1.1(typescript@5.8.3)(zod@3.25.71) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.8.3 transitivePeerDependencies: - zod - ox@0.8.1(typescript@5.8.3)(zod@3.22.4): + ox@0.6.9(typescript@5.8.3)(zod@3.25.71): dependencies: '@adraffy/ens-normalize': 1.11.0 - '@noble/ciphers': 1.3.0 - '@noble/curves': 1.9.2 + '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.0.8(typescript@5.8.3)(zod@3.22.4) + abitype: 1.1.1(typescript@5.8.3)(zod@3.25.71) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.8.3 @@ -12422,11 +13965,71 @@ snapshots: dependencies: '@adraffy/ens-normalize': 1.11.0 '@noble/ciphers': 1.3.0 - '@noble/curves': 1.9.2 + '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.0.8(typescript@5.8.3)(zod@3.25.71) + abitype: 1.1.1(typescript@5.8.3)(zod@3.25.71) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - zod + + ox@0.9.12(typescript@5.8.3)(zod@4.1.12): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + '@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.8.3)(zod@4.1.12) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - zod + + ox@0.9.6(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/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.1.1(typescript@5.8.3)(zod@3.22.4) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - zod + + ox@0.9.6(typescript@5.8.3)(zod@3.25.71): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + '@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.8.3)(zod@3.25.71) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - zod + + ox@0.9.6(typescript@5.8.3)(zod@4.1.12): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + '@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.8.3)(zod@4.1.12) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.8.3 @@ -12457,13 +14060,12 @@ snapshots: dependencies: callsites: 3.1.0 - parse-asn1@5.1.7: + parse-asn1@5.1.9: dependencies: asn1.js: 4.10.1 browserify-aes: 1.2.0 evp_bytestokey: 1.0.3 - hash-base: 3.0.5 - pbkdf2: 3.1.3 + pbkdf2: 3.1.5 safe-buffer: 5.2.1 parse-imports-exports@0.2.4: @@ -12473,7 +14075,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 @@ -12504,20 +14106,20 @@ snapshots: pathval@2.0.1: {} - pbkdf2@3.1.3: + pbkdf2@3.1.5: dependencies: - create-hash: 1.1.3 + create-hash: 1.2.0 create-hmac: 1.1.7 - ripemd160: 2.0.1 + ripemd160: 2.0.3 safe-buffer: 5.2.1 sha.js: 2.4.12 - to-buffer: 1.2.1 + to-buffer: 1.2.2 picocolors@1.1.1: {} picomatch@2.3.1: {} - picomatch@4.0.2: {} + picomatch@4.0.3: {} pify@2.3.0: {} @@ -12551,13 +14153,53 @@ snapshots: pkg-types@1.3.1: dependencies: confbox: 0.1.8 - mlly: 1.7.4 + mlly: 1.8.0 pathe: 2.0.3 pngjs@5.0.0: {} pony-cause@2.1.11: {} + porto@0.2.19(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)))(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71)): + dependencies: + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)) + hono: 4.10.2 + idb-keyval: 6.2.2 + mipd: 0.0.7(typescript@5.8.3) + ox: 0.9.12(typescript@5.8.3)(zod@4.1.12) + viem: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + zod: 4.1.12 + zustand: 5.0.8(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)) + optionalDependencies: + '@tanstack/react-query': 5.90.5(react@19.2.0) + react: 19.2.0 + typescript: 5.8.3 + wagmi: 2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71) + transitivePeerDependencies: + - '@types/react' + - immer + - use-sync-external-store + + porto@0.2.19(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)))(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71)): + dependencies: + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)) + hono: 4.10.2 + idb-keyval: 6.2.2 + mipd: 0.0.7(typescript@5.8.3) + ox: 0.9.12(typescript@5.8.3)(zod@4.1.12) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + zod: 4.1.12 + zustand: 5.0.8(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)) + optionalDependencies: + '@tanstack/react-query': 5.90.5(react@19.2.0) + react: 19.2.0 + typescript: 5.8.3 + wagmi: 2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71) + transitivePeerDependencies: + - '@types/react' + - immer + - use-sync-external-store + possible-typed-array-names@1.1.0: {} postcss-import@15.1.0(postcss@8.5.6): @@ -12565,37 +14207,28 @@ snapshots: postcss: 8.5.6 postcss-value-parser: 4.2.0 read-cache: 1.0.0 - resolve: 1.22.10 + resolve: 1.22.11 - 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 - postcss-load-config@4.0.2(postcss@8.5.6)(ts-node@10.9.2(@types/node@20.19.4)(typescript@5.8.3)): + postcss-load-config@4.0.2(postcss@8.5.6): dependencies: lilconfig: 3.1.3 - yaml: 2.8.0 + yaml: 2.8.1 optionalDependencies: postcss: 8.5.6 - ts-node: 10.9.2(@types/node@20.19.4)(typescript@5.8.3) - postcss-load-config@4.0.2(postcss@8.5.6)(ts-node@10.9.2(@types/node@22.16.0)(typescript@5.8.3)): - dependencies: - lilconfig: 3.1.3 - yaml: 2.8.0 - optionalDependencies: - postcss: 8.5.6 - ts-node: 10.9.2(@types/node@22.16.0)(typescript@5.8.3) - - postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(yaml@2.8.0): + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(yaml@2.8.1): dependencies: lilconfig: 3.1.3 optionalDependencies: jiti: 1.21.7 postcss: 8.5.6 tsx: 4.20.3 - yaml: 2.8.0 + yaml: 2.8.1 postcss-nested@6.2.0(postcss@8.5.6): dependencies: @@ -12621,7 +14254,9 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - preact@10.26.9: {} + preact@10.24.2: {} + + preact@10.27.2: {} prelude-ls@1.2.1: {} @@ -12655,7 +14290,7 @@ snapshots: bn.js: 4.12.2 browserify-rsa: 4.1.1 create-hash: 1.2.0 - parse-asn1: 5.1.7 + parse-asn1: 5.1.9 randombytes: 2.1.0 safe-buffer: 5.2.1 @@ -12714,14 +14349,14 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 - react-dom@19.1.0(react@19.1.0): + react-dom@19.2.0(react@19.2.0): dependencies: - react: 19.1.0 - scheduler: 0.26.0 + react: 19.2.0 + scheduler: 0.27.0 react-is@16.13.1: {} - react@19.1.0: {} + react@19.2.0: {} read-cache@1.0.0: dependencies: @@ -12762,7 +14397,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 @@ -12777,23 +14412,25 @@ 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 require-directory@2.1.1: {} + require-from-string@2.0.2: {} + require-main-filename@2.0.0: {} resolve-from@4.0.0: {} @@ -12802,7 +14439,7 @@ snapshots: resolve-pkg-maps@1.0.0: {} - resolve@1.22.10: + resolve@1.22.11: dependencies: is-core-module: 2.16.1 path-parse: 1.0.7 @@ -12816,43 +14453,40 @@ snapshots: reusify@1.1.0: {} - ripemd160@2.0.1: + ripemd160@2.0.3: dependencies: - hash-base: 2.0.2 + hash-base: 3.1.2 inherits: 2.0.4 - ripemd160@2.0.2: - dependencies: - hash-base: 3.0.5 - inherits: 2.0.4 - - rollup@4.44.1: + rollup@4.52.5: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.44.1 - '@rollup/rollup-android-arm64': 4.44.1 - '@rollup/rollup-darwin-arm64': 4.44.1 - '@rollup/rollup-darwin-x64': 4.44.1 - '@rollup/rollup-freebsd-arm64': 4.44.1 - '@rollup/rollup-freebsd-x64': 4.44.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.44.1 - '@rollup/rollup-linux-arm-musleabihf': 4.44.1 - '@rollup/rollup-linux-arm64-gnu': 4.44.1 - '@rollup/rollup-linux-arm64-musl': 4.44.1 - '@rollup/rollup-linux-loongarch64-gnu': 4.44.1 - '@rollup/rollup-linux-powerpc64le-gnu': 4.44.1 - '@rollup/rollup-linux-riscv64-gnu': 4.44.1 - '@rollup/rollup-linux-riscv64-musl': 4.44.1 - '@rollup/rollup-linux-s390x-gnu': 4.44.1 - '@rollup/rollup-linux-x64-gnu': 4.44.1 - '@rollup/rollup-linux-x64-musl': 4.44.1 - '@rollup/rollup-win32-arm64-msvc': 4.44.1 - '@rollup/rollup-win32-ia32-msvc': 4.44.1 - '@rollup/rollup-win32-x64-msvc': 4.44.1 + '@rollup/rollup-android-arm-eabi': 4.52.5 + '@rollup/rollup-android-arm64': 4.52.5 + '@rollup/rollup-darwin-arm64': 4.52.5 + '@rollup/rollup-darwin-x64': 4.52.5 + '@rollup/rollup-freebsd-arm64': 4.52.5 + '@rollup/rollup-freebsd-x64': 4.52.5 + '@rollup/rollup-linux-arm-gnueabihf': 4.52.5 + '@rollup/rollup-linux-arm-musleabihf': 4.52.5 + '@rollup/rollup-linux-arm64-gnu': 4.52.5 + '@rollup/rollup-linux-arm64-musl': 4.52.5 + '@rollup/rollup-linux-loong64-gnu': 4.52.5 + '@rollup/rollup-linux-ppc64-gnu': 4.52.5 + '@rollup/rollup-linux-riscv64-gnu': 4.52.5 + '@rollup/rollup-linux-riscv64-musl': 4.52.5 + '@rollup/rollup-linux-s390x-gnu': 4.52.5 + '@rollup/rollup-linux-x64-gnu': 4.52.5 + '@rollup/rollup-linux-x64-musl': 4.52.5 + '@rollup/rollup-openharmony-arm64': 4.52.5 + '@rollup/rollup-win32-arm64-msvc': 4.52.5 + '@rollup/rollup-win32-ia32-msvc': 4.52.5 + '@rollup/rollup-win32-x64-gnu': 4.52.5 + '@rollup/rollup-win32-x64-msvc': 4.52.5 fsevents: 2.3.3 - rpc-websockets@9.1.1: + rpc-websockets@9.2.0: dependencies: '@swc/helpers': 0.5.17 '@types/uuid': 8.3.4 @@ -12902,11 +14536,11 @@ snapshots: dependencies: xmlchars: 2.2.0 - scheduler@0.26.0: {} + scheduler@0.27.0: {} semver@6.3.1: {} - semver@7.7.2: {} + semver@7.7.3: {} send@0.19.0: dependencies: @@ -12965,35 +14599,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.2: + sharp@0.34.4: dependencies: - color: 4.2.3 - detect-libc: 2.0.4 - semver: 7.7.2 + '@img/colour': 1.0.0 + detect-libc: 2.1.2 + semver: 7.7.3 optionalDependencies: - '@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 + '@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: @@ -13036,11 +14671,6 @@ snapshots: signal-exit@4.1.0: {} - simple-swizzle@0.2.2: - dependencies: - is-arrayish: 0.3.2 - optional: true - slash@3.0.0: {} snake-case@3.0.4: @@ -13051,7 +14681,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: @@ -13062,7 +14692,7 @@ 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 @@ -13081,9 +14711,9 @@ snapshots: spdx-expression-parse@4.0.0: dependencies: spdx-exceptions: 2.5.0 - spdx-license-ids: 3.0.21 + spdx-license-ids: 3.0.22 - spdx-license-ids@3.0.21: {} + spdx-license-ids@3.0.22: {} split-on-first@1.1.0: {} @@ -13095,7 +14725,7 @@ snapshots: statuses@2.0.1: {} - std-env@3.9.0: {} + std-env@3.10.0: {} stop-iteration-iterator@1.1.0: dependencies: @@ -13115,8 +14745,6 @@ snapshots: stream-shift@1.0.3: {} - streamsearch@1.1.0: {} - strict-uri-encode@2.0.0: {} string-width@4.2.3: @@ -13129,7 +14757,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: @@ -13193,9 +14821,9 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.0: + strip-ansi@7.1.2: dependencies: - ansi-regex: 6.1.0 + ansi-regex: 6.2.2 strip-bom@3.0.0: {} @@ -13203,20 +14831,20 @@ snapshots: strip-json-comments@3.1.1: {} - strip-literal@3.0.0: + strip-literal@3.1.0: dependencies: js-tokens: 9.0.1 - styled-jsx@5.1.6(@babel/core@7.28.0)(react@19.1.0): + styled-jsx@5.1.6(@babel/core@7.28.4)(react@19.2.0): dependencies: client-only: 0.0.1 - react: 19.1.0 + react: 19.2.0 optionalDependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 sucrase@3.35.0: dependencies: - '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/gen-mapping': 0.3.13 commander: 4.1.1 glob: 10.4.5 lines-and-columns: 1.2.4 @@ -13248,13 +14876,13 @@ snapshots: symbol-tree@3.2.4: {} - synckit@0.11.8: + synckit@0.11.11: dependencies: - '@pkgr/core': 0.2.7 + '@pkgr/core': 0.2.9 tailwind-merge@2.6.0: {} - tailwindcss@3.4.17(ts-node@10.9.2(@types/node@20.19.4)(typescript@5.8.3)): + tailwindcss@3.4.18(tsx@4.20.3)(yaml@2.8.1): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -13272,14 +14900,15 @@ 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-load-config: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@types/node@20.19.4)(typescript@5.8.3)) + postcss-js: 4.1.0(postcss@8.5.6) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(yaml@2.8.1) postcss-nested: 6.2.0(postcss@8.5.6) postcss-selector-parser: 6.1.2 - resolve: 1.22.10 + resolve: 1.22.11 sucrase: 3.35.0 transitivePeerDependencies: - - ts-node + - tsx + - yaml text-encoding-utf-8@1.0.2: {} @@ -13299,16 +14928,16 @@ snapshots: tinyexec@0.3.2: {} - tinyglobby@0.2.14: + tinyglobby@0.2.15: dependencies: - fdir: 6.4.6(picomatch@4.0.2) - picomatch: 4.0.2 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 tinypool@1.1.1: {} tinyrainbow@2.0.0: {} - tinyspy@4.0.3: {} + tinyspy@4.0.4: {} tldts-core@6.1.86: {} @@ -13316,7 +14945,7 @@ snapshots: dependencies: tldts-core: 6.1.86 - to-buffer@1.2.1: + to-buffer@1.2.2: dependencies: isarray: 2.0.5 safe-buffer: 5.2.1 @@ -13350,44 +14979,6 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-node@10.9.2(@types/node@20.19.4)(typescript@5.8.3): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 20.19.4 - acorn: 8.15.0 - acorn-walk: 8.3.4 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.8.3 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - optional: true - - ts-node@10.9.2(@types/node@22.16.0)(typescript@5.8.3): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 22.16.0 - acorn: 8.15.0 - acorn-walk: 8.3.4 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.8.3 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - optional: true - tsconfck@3.1.6(typescript@5.8.3): optionalDependencies: typescript: 5.8.3 @@ -13403,19 +14994,19 @@ snapshots: tslib@2.8.1: {} - tsup@7.3.0(postcss@8.5.6)(ts-node@10.9.2(@types/node@22.16.0)(typescript@5.8.3))(typescript@5.8.3): + tsup@7.3.0(postcss@8.5.6)(typescript@5.8.3): dependencies: 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)(ts-node@10.9.2(@types/node@22.16.0)(typescript@5.8.3)) + postcss-load-config: 4.0.2(postcss@8.5.6) resolve-from: 5.0.0 - rollup: 4.44.1 + rollup: 4.52.5 source-map: 0.8.0-beta.0 sucrase: 3.35.0 tree-kill: 1.2.2 @@ -13426,24 +15017,24 @@ snapshots: - supports-color - ts-node - tsup@8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0): + tsup@8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.1): dependencies: 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 + debug: 4.4.3 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.3)(yaml@2.8.0) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.3)(yaml@2.8.1) resolve-from: 5.0.0 - rollup: 4.44.1 + rollup: 4.52.5 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 @@ -13529,54 +15120,54 @@ snapshots: 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: {} unpipe@1.0.0: {} - unrs-resolver@1.10.1: + unrs-resolver@1.11.1: dependencies: - napi-postinstall: 0.3.0 + napi-postinstall: 0.3.4 optionalDependencies: - '@unrs/resolver-binding-android-arm-eabi': 1.10.1 - '@unrs/resolver-binding-android-arm64': 1.10.1 - '@unrs/resolver-binding-darwin-arm64': 1.10.1 - '@unrs/resolver-binding-darwin-x64': 1.10.1 - '@unrs/resolver-binding-freebsd-x64': 1.10.1 - '@unrs/resolver-binding-linux-arm-gnueabihf': 1.10.1 - '@unrs/resolver-binding-linux-arm-musleabihf': 1.10.1 - '@unrs/resolver-binding-linux-arm64-gnu': 1.10.1 - '@unrs/resolver-binding-linux-arm64-musl': 1.10.1 - '@unrs/resolver-binding-linux-ppc64-gnu': 1.10.1 - '@unrs/resolver-binding-linux-riscv64-gnu': 1.10.1 - '@unrs/resolver-binding-linux-riscv64-musl': 1.10.1 - '@unrs/resolver-binding-linux-s390x-gnu': 1.10.1 - '@unrs/resolver-binding-linux-x64-gnu': 1.10.1 - '@unrs/resolver-binding-linux-x64-musl': 1.10.1 - '@unrs/resolver-binding-wasm32-wasi': 1.10.1 - '@unrs/resolver-binding-win32-arm64-msvc': 1.10.1 - '@unrs/resolver-binding-win32-ia32-msvc': 1.10.1 - '@unrs/resolver-binding-win32-x64-msvc': 1.10.1 - - unstorage@1.16.0(idb-keyval@6.2.2): + '@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.1(idb-keyval@6.2.2): dependencies: anymatch: 3.1.3 chokidar: 4.0.3 destr: 2.0.5 - h3: 1.15.3 + h3: 1.15.4 lru-cache: 10.4.3 - node-fetch-native: 1.6.6 + node-fetch-native: 1.6.7 ofetch: 1.4.1 ufo: 1.6.1 optionalDependencies: idb-keyval: 6.2.2 - update-browserslist-db@1.1.3(browserslist@4.25.1): + update-browserslist-db@1.1.4(browserslist@4.27.0): dependencies: - browserslist: 4.25.1 + browserslist: 4.27.0 escalade: 3.2.0 picocolors: 1.1.1 @@ -13584,13 +15175,13 @@ snapshots: dependencies: punycode: 2.3.1 - use-sync-external-store@1.2.0(react@19.1.0): + use-sync-external-store@1.2.0(react@19.2.0): dependencies: - react: 19.1.0 + react: 19.2.0 - use-sync-external-store@1.4.0(react@19.1.0): + use-sync-external-store@1.4.0(react@19.2.0): dependencies: - react: 19.1.0 + react: 19.2.0 utf-8-validate@5.0.10: dependencies: @@ -13602,7 +15193,7 @@ snapshots: dependencies: inherits: 2.0.4 is-arguments: 1.2.0 - is-generator-function: 1.1.0 + is-generator-function: 1.1.2 is-typed-array: 1.1.15 which-typed-array: 1.1.19 @@ -13612,17 +15203,14 @@ snapshots: uuid@9.0.1: {} - v8-compile-cache-lib@3.0.1: - optional: true - - valtio@1.13.2(@types/react@19.1.8)(react@19.1.0): + valtio@1.13.2(@types/react@19.2.2)(react@19.2.0): dependencies: - derive-valtio: 0.1.0(valtio@1.13.2(@types/react@19.1.8)(react@19.1.0)) + derive-valtio: 0.1.0(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0)) proxy-compare: 2.6.0 - use-sync-external-store: 1.2.0(react@19.1.0) + use-sync-external-store: 1.2.0(react@19.2.0) optionalDependencies: - '@types/react': 19.1.8 - react: 19.1.0 + '@types/react': 19.2.2 + react: 19.2.0 vary@1.1.2: {} @@ -13643,15 +15231,15 @@ snapshots: - utf-8-validate - zod - viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4): + viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71): dependencies: '@noble/curves': 1.9.2 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.0.8(typescript@5.8.3)(zod@3.22.4) + abitype: 1.0.8(typescript@5.8.3)(zod@3.25.71) 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) + ox: 0.8.1(typescript@5.8.3)(zod@3.25.71) ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: typescript: 5.8.3 @@ -13660,16 +15248,50 @@ snapshots: - utf-8-validate - zod - viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71): + viem@2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4): dependencies: - '@noble/curves': 1.9.2 + '@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.8.3)(zod@3.25.71) - 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.71) - ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) + abitype: 1.1.0(typescript@5.8.3)(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.8.3)(zod@3.22.4) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71): + 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.8.3)(zod@3.25.71) + isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.9.6(typescript@5.8.3)(zod@3.25.71) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@4.1.12): + 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.8.3)(zod@4.1.12) + isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.9.6(typescript@5.8.3)(zod@4.1.12) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: typescript: 5.8.3 transitivePeerDependencies: @@ -13677,13 +15299,13 @@ snapshots: - utf-8-validate - zod - vite-node@3.2.4(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0): + vite-node@3.2.4(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(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.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) transitivePeerDependencies: - '@types/node' - jiti @@ -13698,56 +15320,56 @@ snapshots: - tsx - yaml - vite-tsconfig-paths@5.1.4(typescript@5.8.3)(vite@6.3.5(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0)): + vite-tsconfig-paths@5.1.4(typescript@5.8.3)(vite@6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1)): dependencies: - debug: 4.4.1 + debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.8.3) optionalDependencies: - vite: 6.3.5(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) transitivePeerDependencies: - supports-color - typescript - vite@6.3.5(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0): + vite@6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1): dependencies: esbuild: 0.25.5 - fdir: 6.4.6(picomatch@4.0.2) - picomatch: 4.0.2 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.44.1 - tinyglobby: 0.2.14 + rollup: 4.52.5 + tinyglobby: 0.2.15 optionalDependencies: '@types/node': 22.16.0 fsevents: 2.3.3 jiti: 1.21.7 tsx: 4.20.3 - yaml: 2.8.0 + yaml: 2.8.1 - vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.16.0)(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.16.0)(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.1): dependencies: - '@types/chai': 5.2.2 + '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0)) + '@vitest/mocker': 3.2.4(vite@6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(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.2.0 - debug: 4.4.1 - expect-type: 1.2.1 - magic-string: 0.30.17 + chai: 5.3.3 + debug: 4.4.3 + expect-type: 1.2.2 + magic-string: 0.30.19 pathe: 2.0.3 - picomatch: 4.0.2 - std-env: 3.9.0 + picomatch: 4.0.3 + std-env: 3.10.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.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) - vite-node: 3.2.4(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.4.1(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) + vite-node: 3.2.4(@types/node@22.16.0)(jiti@1.21.7)(tsx@4.20.3)(yaml@2.8.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 @@ -13771,13 +15393,13 @@ snapshots: dependencies: xml-name-validator: 5.0.0 - wagmi@2.15.6(@tanstack/query-core@5.81.5)(@tanstack/react-query@5.81.5(react@19.1.0))(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71): + wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71): dependencies: - '@tanstack/react-query': 5.81.5(react@19.1.0) - '@wagmi/connectors': 5.8.5(@types/react@19.1.8)(@wagmi/core@2.17.3(@tanstack/query-core@5.81.5)(@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.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)))(bufferutil@4.0.9)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71) - '@wagmi/core': 2.17.3(@tanstack/query-core@5.81.5)(@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.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)) - react: 19.1.0 - use-sync-external-store: 1.4.0(react@19.1.0) + '@tanstack/react-query': 5.90.5(react@19.2.0) + '@wagmi/connectors': 6.1.0(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)))(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71))(zod@3.25.71) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)) + react: 19.2.0 + use-sync-external-store: 1.4.0(react@19.2.0) viem: 2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) optionalDependencies: typescript: 5.8.3 @@ -13797,6 +15419,46 @@ snapshots: - '@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.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71): + dependencies: + '@tanstack/react-query': 5.90.5(react@19.2.0) + '@wagmi/connectors': 6.1.0(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)))(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.31.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71))(zod@3.25.71))(zod@3.25.71) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71)) + react: 19.2.0 + use-sync-external-store: 1.4.0(react@19.2.0) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.71) + optionalDependencies: + typescript: 5.8.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' + - '@tanstack/query-core' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -13855,7 +15517,7 @@ snapshots: is-async-function: 2.1.1 is-date-object: 1.1.0 is-finalizationregistry: 1.1.1 - is-generator-function: 1.1.0 + is-generator-function: 1.1.2 is-regex: 1.2.1 is-weakref: 1.1.1 isarray: 2.0.5 @@ -13907,9 +15569,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: {} @@ -13950,7 +15612,7 @@ snapshots: yallist@3.1.1: {} - yaml@2.8.0: {} + yaml@2.8.1: {} yargs-parser@18.1.3: dependencies: @@ -13971,17 +15633,28 @@ snapshots: y18n: 4.0.3 yargs-parser: 18.1.3 - yn@3.1.1: - optional: true - yocto-queue@0.1.0: {} zod@3.22.4: {} zod@3.25.71: {} - zustand@5.0.0(@types/react@19.1.8)(react@19.1.0)(use-sync-external-store@1.4.0(react@19.1.0)): + zod@4.1.12: {} + + zustand@5.0.0(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)): + optionalDependencies: + '@types/react': 19.2.2 + react: 19.2.0 + use-sync-external-store: 1.4.0(react@19.2.0) + + zustand@5.0.3(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)): + optionalDependencies: + '@types/react': 19.2.2 + react: 19.2.0 + use-sync-external-store: 1.4.0(react@19.2.0) + + zustand@5.0.8(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)): optionalDependencies: - '@types/react': 19.1.8 - react: 19.1.0 - use-sync-external-store: 1.4.0(react@19.1.0) + '@types/react': 19.2.2 + react: 19.2.0 + use-sync-external-store: 1.4.0(react@19.2.0) diff --git a/e2e/pnpm-workspace.yaml b/e2e/pnpm-workspace.yaml index 752368a67..f9d1505f9 100644 --- a/e2e/pnpm-workspace.yaml +++ b/e2e/pnpm-workspace.yaml @@ -1,4 +1,10 @@ packages: + - "facilitators/*" - "servers/*" - "clients/*" + - "legacy/servers/*" + - "legacy/clients/*" - "../typescript/packages/*" + - "../typescript/packages/http/*" + - "../typescript/packages/mechanisms/*" + - "../typescript/packages/legacy/*" diff --git a/e2e/servers/express/README.md b/e2e/servers/express/README.md index 5adab235c..fdcff3ab0 100644 --- a/e2e/servers/express/README.md +++ b/e2e/servers/express/README.md @@ -1,146 +1,113 @@ -# x402-express Example Server +# x402 Express E2E Test Server -This is an example Express.js server that demonstrates how to use the `x402-express` middleware to implement paywall functionality in your API endpoints. +This directory contains an Express server configured with x402 payment middleware for end-to-end testing. -## Prerequisites +## Overview -- Node.js v20+ (install via [nvm](https://github.com/nvm-sh/nvm)) -- pnpm v10 (install via [pnpm.io/installation](https://pnpm.io/installation)) -- A valid Ethereum address for receiving payments -- Coinbase Developer Platform API Key & Secret (if accepting payments on Base mainnet) - -- Get them here [https://portal.cdp.coinbase.com/projects](https://portal.cdp.coinbase.com/projects) +The server demonstrates how to integrate x402 payment protection into an Express application. It includes: + +- **Payment-protected endpoints** requiring micropayments to access +- **Local facilitator** for testing without external dependencies +- **EVM support** for Base Sepolia testnet transactions ## Setup -1. Copy `.env-local` to `.env` and add your Ethereum address to receive payments: +### Prerequisites -```bash -cp .env-local .env -``` +1. Node.js and pnpm installed +2. Environment variables configured: + ```bash + EVM_PRIVATE_KEY=0x... # Private key for facilitator account + EVM_ADDRESS=0x... # Address to receive payments + PORT=4021 # Optional: server port (defaults to 4021) + ``` + +### Installation -2. Install and build all packages from the typescript examples root: ```bash -cd ../../ pnpm install -pnpm build -cd servers/express ``` -3. Run the server +### Running the Server + ```bash -pnpm install -pnpm dev +pnpm run start ``` -## Testing the Server +Or for development with auto-reload: -You can test the server using one of the example clients: - -### Using the Fetch Client ```bash -cd ../clients/fetch -# Ensure .env is setup -pnpm install -pnpm dev +pnpm run dev ``` -### Using the Axios Client +## Endpoints + +### Protected Endpoint +- **GET /protected** - Requires $0.001 USDC payment on Base Sepolia +- Returns success message with timestamp when payment is valid + +### Utility Endpoints +- **GET /health** - Health check (no payment required) +- **POST /close** - Gracefully shutdown server (for testing) + +## Architecture + +### Components + +1. **`index.ts`** - Main server file with Express app and route configuration +2. **`facilitator.ts`** - Local facilitator setup for payment processing + +### Payment Flow + +1. Client requests protected endpoint +2. Server returns 402 Payment Required with payment instructions +3. Client creates and signs payment +4. Client retries request with payment signature +5. Server verifies payment via facilitator +6. If valid, server processes request and settles payment +7. Server returns response with settlement confirmation + +## Testing + +This server is used by the e2e test suite to verify x402 client implementations. The local facilitator allows testing without relying on external services. + +### Running E2E Tests + +From the project root: + ```bash -cd ../clients/axios -# Ensure .env is setup -pnpm install -pnpm dev +pnpm run test:e2e ``` -These clients will demonstrate how to: -1. Make an initial request to get payment requirements -2. Process the payment requirements -3. Make a second request with the payment token - -## Example Endpoint - -The server includes a single example endpoint at `/weather` that requires a payment of $0.001 to access. The endpoint returns a simple weather report. - -## Response Format - -### Payment Required (402) -```json -{ - "error": "X-PAYMENT header is required", - "paymentRequirements": { - "scheme": "exact", - "network": "base", - "maxAmountRequired": "1000", - "resource": "http://localhost:4021/weather", - "description": "", - "mimeType": "", - "payTo": "0xYourAddress", - "maxTimeoutSeconds": 60, - "asset": "0x...", - "outputSchema": null, - "extra": null - } -} -``` +## Production Considerations -### Successful Response -```ts -// Body -{ - "report": { - "weather": "sunny", - "temperature": 70 - } -} -// Headers -{ - "X-PAYMENT-RESPONSE": "..." // Encoded response object -} -``` +For production use: -## Extending the Example - -To add more paid endpoints, follow this pattern: - -```typescript -// First, configure the payment middleware with your routes -app.use( - paymentMiddleware( - payTo, - { - // Define your routes and their payment requirements - "GET /your-endpoint": { - price: "$0.10", - network: "base-sepolia", - }, - "/premium/*": { - price: { - amount: "100000", - asset: { - address: "0xabc", - decimals: 18, - eip712: { - name: "WETH", - version: "1", - }, - }, - }, - network: "base-sepolia", - }, - }, - ), -); - -// Then define your routes as normal -app.get("/your-endpoint", (req, res) => { - res.json({ - // Your response data - }); -}); - -app.get("/premium/content", (req, res) => { - res.json({ - content: "This is premium content", - }); -}); -``` +1. Replace the local facilitator with a remote facilitator service +2. Configure appropriate payment amounts and networks +3. Add proper error handling and logging +4. Implement rate limiting and security measures +5. Use environment-specific configuration + +## Troubleshooting + +### Common Issues + +1. **"EVM_PRIVATE_KEY environment variable is required"** + - Ensure `.env` file exists with required variables + - Check that dotenv is loading correctly + +2. **"Server already running on port"** + - Check for existing processes: `lsof -i :4021` + - Kill existing process or use different port + +3. **Payment verification fails** + - Verify private key matches the expected account + - Check network configuration matches client + - Ensure sufficient balance for gas fees + +## Related Documentation + +- [x402 Protocol Specification](../../../specs/x402-specification.md) +- [Express Middleware Package](../../../typescript/packages/http/express/README.md) +- [E2E Test Suite](../../README.md) \ No newline at end of file diff --git a/e2e/servers/express/index.ts b/e2e/servers/express/index.ts index a7647eb6b..1a00c008e 100644 --- a/e2e/servers/express/index.ts +++ b/e2e/servers/express/index.ts @@ -1,50 +1,97 @@ import express from "express"; -import { Network, paymentMiddleware, SolanaAddress } from "x402-express"; -import { facilitator } from "@coinbase/x402"; +import { paymentMiddleware } from "@x402/express"; +import { ExactEvmService } from "@x402/evm"; +import { HTTPFacilitatorClient } from "@x402/core/server"; +import { declareDiscoveryExtension, BAZAAR } from "@x402/extensions/bazaar"; import dotenv from "dotenv"; dotenv.config(); -const useCdpFacilitator = process.env.USE_CDP_FACILITATOR === 'true'; -const evmNetwork = process.env.EVM_NETWORK as Network; -const svmNetwork = process.env.SVM_NETWORK as Network; -const payToEvm = process.env.EVM_ADDRESS as `0x${string}`; -const payToSvm = process.env.SVM_ADDRESS as SolanaAddress; -const port = process.env.PORT || "4021"; +/** + * Express E2E Test Server with x402 Payment Middleware + * + * This server demonstrates how to integrate x402 payment middleware + * with an Express application for end-to-end testing. + */ -if (!payToEvm || !evmNetwork) { - console.error("Missing required environment variables"); +const PORT = process.env.PORT || "4021"; +const NETWORK = "eip155:84532" as const; +const PAYEE_ADDRESS = process.env.EVM_ADDRESS as `0x${string}`; +const facilitatorUrl = process.env.FACILITATOR_URL; + +if (!PAYEE_ADDRESS) { + console.error("āŒ EVM_ADDRESS environment variable is required"); process.exit(1); } +if (!facilitatorUrl) { + console.error("āŒ FACILITATOR_URL environment variable is required"); + process.exit(1); +} + +// Initialize Express app const app = express(); +// Create HTTP facilitator client +const facilitatorClient = new HTTPFacilitatorClient({ url: facilitatorUrl }); +console.log(`Facilitator account: ${process.env.EVM_PRIVATE_KEY ? process.env.EVM_PRIVATE_KEY.substring(0, 10) + '...' : 'not configured'}`); +console.log(`Using remote facilitator at: ${facilitatorUrl}`); + +/** + * Configure x402 payment middleware + * + * This middleware protects the /protected endpoint with a $0.001 USDC payment requirement + * on the Base Sepolia testnet with bazaar discovery extension. + */ app.use( paymentMiddleware( - payToEvm, { + // Route-specific payment configuration "GET /protected": { + payTo: PAYEE_ADDRESS, + scheme: "exact", price: "$0.001", - network: evmNetwork, + network: NETWORK, + extensions: { + [BAZAAR]: declareDiscoveryExtension({ + method: "GET", + output: { + example: { + message: "Protected endpoint accessed successfully", + timestamp: "2024-01-01T00:00:00Z", + }, + schema: { + properties: { + message: { type: "string" }, + timestamp: { type: "string" }, + }, + required: ["message", "timestamp"], + }, + }, + }), + }, }, }, - useCdpFacilitator ? facilitator : undefined - ), -); - -app.use( - paymentMiddleware( - payToSvm, - { - "GET /protected-svm": { - price: "$0.001", - network: svmNetwork, + // Use facilitator (either remote or local) + facilitatorClient, + // Register the EVM server for handling exact payments + [ + { + network: NETWORK, + server: new ExactEvmService(), }, - }, - useCdpFacilitator ? facilitator : undefined + ], + // No custom paywall configuration (uses defaults) + undefined, ), ); +/** + * Protected endpoint - requires payment to access + * + * This endpoint demonstrates a resource protected by x402 payment middleware. + * Clients must provide a valid payment signature to access this endpoint. + */ app.get("/protected", (req, res) => { res.json({ message: "Protected endpoint accessed successfully", @@ -52,23 +99,49 @@ app.get("/protected", (req, res) => { }); }); -app.get("/protected-svm", (req, res) => { +/** + * Health check endpoint - no payment required + * + * Used to verify the server is running and responsive. + */ +app.get("/health", (req, res) => { res.json({ - message: "Protected endpoint #2 accessed successfully", - timestamp: new Date().toISOString(), + status: "ok", + network: NETWORK, + payee: PAYEE_ADDRESS, + version: "2.0.0", }); }); -app.get("/health", (req, res) => { - res.json({ status: "ok" }); -}); - +/** + * Shutdown endpoint - used by e2e tests + * + * Allows graceful shutdown of the server during testing. + */ app.post("/close", (req, res) => { - res.json({ message: "Server shutting down" }); + res.json({ message: "Server shutting down gracefully" }); console.log("Received shutdown request"); - process.exit(0); + + // Give time for response to be sent + setTimeout(() => { + process.exit(0); + }, 100); }); -app.listen(parseInt(port), () => { - console.log(`Server listening at http://localhost:${port}`); -}); \ No newline at end of file +// Start the server +app.listen(parseInt(PORT), () => { + console.log(` +╔════════════════════════════════════════════════════════╗ +ā•‘ x402 Express E2E Test Server ā•‘ +╠════════════════════════════════════════════════════════╣ +ā•‘ Server: http://localhost:${PORT} ā•‘ +ā•‘ Network: ${NETWORK} ā•‘ +ā•‘ Payee: ${PAYEE_ADDRESS} ā•‘ +ā•‘ ā•‘ +ā•‘ Endpoints: ā•‘ +ā•‘ • GET /protected (requires $0.001 USDC payment) ā•‘ +ā•‘ • GET /health (no payment required) ā•‘ +ā•‘ • POST /close (shutdown server) ā•‘ +ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā• + `); +}); diff --git a/e2e/servers/express/package.json b/e2e/servers/express/package.json index c73330731..d3ae4c05b 100644 --- a/e2e/servers/express/package.json +++ b/e2e/servers/express/package.json @@ -1,5 +1,5 @@ { - "name": "express-e2e", + "name": "@x402/express-e2e", "private": true, "type": "module", "scripts": { @@ -10,10 +10,12 @@ "lint:check": "eslint . --ext .ts" }, "dependencies": { - "@coinbase/x402": "workspace:*", + "@x402/core": "workspace:*", + "@x402/express": "workspace:*", + "@x402/evm": "workspace:*", + "@x402/extensions": "workspace:*", "dotenv": "^16.6.1", - "express": "^4.18.2", - "x402-express": "workspace:*" + "express": "^4.18.2" }, "devDependencies": { "@eslint/js": "^9.24.0", diff --git a/e2e/servers/express/test.config.json b/e2e/servers/express/test.config.json index 0e426e6c7..fe5043668 100644 --- a/e2e/servers/express/test.config.json +++ b/e2e/servers/express/test.config.json @@ -2,6 +2,10 @@ "name": "express", "type": "server", "language": "typescript", + "x402Version": 2, + "extensions": [ + "bazaar" + ], "endpoints": [ { "path": "/protected", @@ -10,13 +14,6 @@ "requiresPayment": true, "protocolFamily": "evm" }, - { - "path": "/protected-svm", - "method": "GET", - "description": "Protected endpoint requiring payment on SVM network", - "requiresPayment": true, - "protocolFamily": "svm" - }, { "path": "/health", "method": "GET", @@ -33,15 +30,9 @@ "environment": { "required": [ "PORT", - "USE_CDP_FACILITATOR", - "EVM_NETWORK", - "SVM_NETWORK", "EVM_ADDRESS", - "SVM_ADDRESS" + "FACILITATOR_URL" ], - "optional": [ - "CDP_API_KEY_ID", - "CDP_API_KEY_SECRET" - ] + "optional": [] } } \ No newline at end of file diff --git a/e2e/servers/gin/.gitignore b/e2e/servers/gin/.gitignore new file mode 100644 index 000000000..556a7128f --- /dev/null +++ b/e2e/servers/gin/.gitignore @@ -0,0 +1,8 @@ +# Binaries +gin-server +main + +# Environment files +.env +.env.local + diff --git a/e2e/servers/gin/IMPLEMENTATION.md b/e2e/servers/gin/IMPLEMENTATION.md new file mode 100644 index 000000000..38509ae2a --- /dev/null +++ b/e2e/servers/gin/IMPLEMENTATION.md @@ -0,0 +1,263 @@ +# Gin v2 Server Implementation Summary + +## Overview + +This is a new **v2 Gin server** implementation for E2E testing, parallel to the existing v2 Express server. It uses the new v2 middleware from `go/http/gin/middleware.go`. + +## Key Differences from Legacy Gin Server + +| Aspect | Legacy (`e2e/legacy/servers/gin`) | v2 (`e2e/servers/gin`) | +|--------|----------------------------------|------------------------| +| **x402 Version** | v1 | v2 | +| **Package Import** | `github.com/coinbase/x402/go/pkg/gin` | `github.com/coinbase/x402-go/v2/http/gin` | +| **Network Format** | `"base-sepolia"` (string) | `"eip155:84532"` (CAIP-2) | +| **Middleware API** | Function-based with options | Route-based configuration | +| **Service Registration** | Implicit | Explicit via `WithScheme()` | +| **Facilitator Config** | `types.FacilitatorConfig` | `x402http.FacilitatorConfig` | + +## Architecture + +``` +ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” +│ Gin Framework │ +│ (ginfw) │ +ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ + │ + ā–¼ +ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” +│ x402 v2 Gin │ +│ Middleware │◄────── Routes Config +ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ + │ + ā”œā”€ā”€ā”€ā”€ā”€ā”€ā–ŗ Facilitator Client (HTTP) + │ + └──────► EVM Service (ExactEvmService) +``` + +## File Structure + +``` +e2e/servers/gin/ +ā”œā”€ā”€ main.go # Server implementation +ā”œā”€ā”€ go.mod # Go module dependencies +ā”œā”€ā”€ go.sum # Dependency checksums +ā”œā”€ā”€ test.config.json # E2E test configuration +ā”œā”€ā”€ run.sh # Startup script +ā”œā”€ā”€ README.md # User documentation +ā”œā”€ā”€ IMPLEMENTATION.md # This file +└── .gitignore # Git ignore rules +``` + +## Configuration + +### Environment Variables (Required) + +- `PORT`: Server port +- `EVM_ADDRESS`: Ethereum address to receive payments +- `FACILITATOR_URL`: URL of the facilitator service + +### Test Config (`test.config.json`) + +```json +{ + "name": "gin", + "type": "server", + "language": "go", + "x402Version": 2, + "endpoints": [ + { + "path": "/protected", + "method": "GET", + "requiresPayment": true, + "protocolFamily": "evm" + }, + { + "path": "/health", + "method": "GET", + "health": true + }, + { + "path": "/close", + "method": "POST", + "close": true + } + ] +} +``` + +## Implementation Details + +### 1. Package Imports + +Using v2 packages with proper aliasing to avoid conflicts: + +```go +import ( + x402 "github.com/coinbase/x402-go/v2" + x402http "github.com/coinbase/x402-go/v2/http" + "github.com/coinbase/x402-go/v2/http/gin" + "github.com/coinbase/x402-go/v2/mechanisms/evm" + ginfw "github.com/gin-gonic/gin" // Aliased to avoid conflict +) +``` + +### 2. Middleware Configuration + +Routes-based configuration matching Express v2 style: + +```go +routes := x402http.RoutesConfig{ + "GET /protected": { + Scheme: "exact", + PayTo: payeeAddress, + Price: "$0.001", + Network: network, + }, +} +``` + +### 3. Service Registration + +Explicit EVM service registration: + +```go +evmService := evm.NewExactEvmService() + +r.Use(gin.PaymentMiddleware( + routes, + gin.WithFacilitatorClient(facilitatorClient), + gin.WithScheme(network, evmService), + gin.WithInitializeOnStart(true), + gin.WithTimeout(30*time.Second), +)) +``` + +### 4. Remote Facilitator + +Uses HTTP facilitator client: + +```go +facilitatorClient := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{ + URL: facilitatorURL, +}) +``` + +## Testing + +### Automatic Discovery + +The E2E test runner will automatically discover this server because: + +1. āœ… Located in `e2e/servers/gin/` +2. āœ… Has `test.config.json` with `"type": "server"` +3. āœ… Has executable `run.sh` script +4. āœ… Declares `"x402Version": 2` + +### Running Tests + +```bash +# Run all v2 tests (includes this server) +cd e2e +pnpm test + +# Run all tests including legacy +pnpm test --legacy +``` + +### Expected Test Scenarios + +With this server, the test suite will create scenarios like: + +- āœ… `fetch → gin → /protected via typescript` +- āœ… `fetch → gin → /protected via go` +- āœ… `go-http → gin → /protected via typescript` +- āœ… `go-http → gin → /protected via go` + +## Payment Flow + +1. **Request without payment** + ``` + GET /protected + ``` + +2. **Server returns 402** + ```json + { + "error": "Payment required", + "accepts": [{ ... }], + "x402_version": 2 + } + ``` + +3. **Client creates payment via facilitator** + +4. **Client retries with X-Payment header** + ``` + GET /protected + X-Payment: + ``` + +5. **Middleware verifies payment with facilitator** + +6. **Server returns protected content** + ```json + { + "message": "Protected endpoint accessed successfully", + "timestamp": "2024-10-26T19:00:00Z" + } + ``` + +7. **Server settles payment and returns X-Payment-Response** + +## Troubleshooting + +### Build Errors + +If you get build errors: + +```bash +cd e2e/servers/gin +go mod tidy +go build +``` + +### Server Won't Start + +Check that all required environment variables are set: + +```bash +export PORT=4021 +export EVM_ADDRESS=0x... +export FACILITATOR_URL=http://localhost:4022 +./run.sh +``` + +### Not Discovered by Tests + +Verify: +1. File is at `e2e/servers/gin/test.config.json` +2. `run.sh` is executable: `chmod +x run.sh` +3. Config has `"type": "server"` and `"x402Version": 2` + +## Related Files + +- **v2 Middleware**: `go/http/gin/middleware.go` +- **Legacy Gin Server**: `e2e/legacy/servers/gin/main.go` +- **v2 Express Server**: `e2e/servers/express/index.ts` +- **Test Runner**: `e2e/test.ts` +- **Discovery Logic**: `e2e/src/discovery.ts` + +## Success Criteria + +āœ… Server compiles without errors +āœ… Server starts and logs "Server listening" +āœ… Health check endpoint responds +āœ… Protected endpoint returns 402 without payment +āœ… Payment flow completes successfully +āœ… Graceful shutdown works via /close endpoint +āœ… Test suite discovers and tests the server + +## Status + +šŸŽ‰ **COMPLETE** - Implementation finished and ready for testing! + diff --git a/e2e/servers/gin/README.md b/e2e/servers/gin/README.md new file mode 100644 index 000000000..b66073b15 --- /dev/null +++ b/e2e/servers/gin/README.md @@ -0,0 +1,158 @@ +# Gin x402 v2 E2E Test Server + +This is a Go Gin server implementation for x402 v2 protocol end-to-end testing. + +## Overview + +This server demonstrates how to integrate x402 v2 payment middleware with a Gin application. It uses the new v2 middleware from `go/http/gin/middleware.go` and provides a protected endpoint that requires payment. + +## Features + +- **x402 v2 Protocol Support**: Uses the latest v2 protocol specification +- **EVM Support**: Handles Ethereum Virtual Machine compatible payments (Base Sepolia) +- **Remote Facilitator**: Connects to an external facilitator service for payment processing +- **Payment Protection**: Protects endpoints with configurable payment requirements +- **Health Checks**: Provides health check endpoint for monitoring +- **Graceful Shutdown**: Supports graceful shutdown for testing + +## Architecture + +``` +ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” +│ Client │ +ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ + │ 1. GET /protected + │ + ā–¼ +ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” +│ Gin Middleware │ ◄──────┐ +│ (x402 v2) │ │ 3. Verify +ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ │ payment + │ │ + │ 2. Request │ + │ payment │ + ā–¼ │ +ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ +│ Facilitator ā”‚ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ +│ Service │ +ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ +``` + +## Configuration + +### Environment Variables + +- `PORT`: Server port (default: 4021) +- `EVM_ADDRESS`: Ethereum address to receive payments (required) +- `FACILITATOR_URL`: URL of the facilitator service (required) + +### Endpoints + +#### `GET /protected` +Protected endpoint requiring $0.001 USDC payment on Base Sepolia. + +**Success Response (200)**: +```json +{ + "message": "Protected endpoint accessed successfully", + "timestamp": "2024-01-01T00:00:00Z" +} +``` + +#### `GET /health` +Health check endpoint (no payment required). + +**Response (200)**: +```json +{ + "status": "ok", + "network": "eip155:84532", + "payee": "0x...", + "version": "2.0.0" +} +``` + +#### `POST /close` +Graceful shutdown endpoint for testing cleanup. + +**Response (200)**: +```json +{ + "message": "Server shutting down gracefully" +} +``` + +## Running the Server + +### Development + +```bash +# Set environment variables +export PORT=4021 +export EVM_ADDRESS=0x1234567890123456789012345678901234567890 +export FACILITATOR_URL=http://localhost:4022 + +# Run the server +./run.sh +``` + +### Production + +```bash +# Build +go build -o gin-server main.go + +# Run +./gin-server +``` + +## Payment Flow + +1. Client makes request to `/protected` without payment +2. Middleware returns 402 Payment Required with payment details +3. Client creates payment signature using facilitator +4. Client retries request with X-Payment header +5. Middleware verifies payment with facilitator +6. Server processes request and returns protected content +7. Server settles payment and returns X-Payment-Response header + +## Testing + +This server is designed for E2E testing and integrates with the test suite in `e2e/test.ts`. + +To run the E2E tests: + +```bash +cd ../.. +pnpm test +``` + +To run with legacy servers: + +```bash +pnpm test --legacy +``` + +## Differences from v1 + +The v2 implementation differs from v1 in several key ways: + +1. **Network Format**: Uses CAIP-2 format (`eip155:84532`) instead of legacy strings (`base-sepolia`) +2. **Middleware API**: Uses new v2 middleware with different configuration structure +3. **Facilitator Integration**: Uses `HTTPFacilitatorClient` instead of legacy config +4. **Scheme Registration**: Explicitly registers EVM scheme service +5. **Type Safety**: Improved type safety with v2 types and interfaces + +## Dependencies + +- `github.com/coinbase/x402-go/v2`: x402 v2 protocol implementation +- `github.com/gin-gonic/gin`: Gin web framework +- `github.com/joho/godotenv`: Environment variable loading + +## Development Notes + +- Server logs are minimal in release mode for cleaner E2E test output +- Graceful shutdown is handled via `/close` endpoint and OS signals +- Payment verification is handled by the middleware before reaching handlers +- All payment-related errors return 402 status with JSON error details + diff --git a/e2e/servers/gin/go.mod b/e2e/servers/gin/go.mod index 078542b14..4a7371db6 100644 --- a/e2e/servers/gin/go.mod +++ b/e2e/servers/gin/go.mod @@ -3,39 +3,43 @@ module github.com/coinbase/x402/e2e/servers/gin go 1.23.3 require ( - github.com/coinbase/x402/go v0.0.0-00010101000000-000000000000 - github.com/gin-gonic/gin v1.10.0 + github.com/coinbase/x402-go/v2 v2.0.0 + github.com/gin-gonic/gin v1.11.0 github.com/joho/godotenv v1.5.1 ) require ( - github.com/bytedance/sonic v1.13.2 // indirect - github.com/bytedance/sonic/loader v0.2.4 // indirect - github.com/cloudwego/base64x v0.1.5 // indirect - github.com/coinbase/cdp-sdk/go v0.0.0-20250506223104-85d38372d771 // indirect + github.com/bytedance/sonic v1.14.0 // indirect + github.com/bytedance/sonic/loader v0.3.0 // indirect + github.com/cloudwego/base64x v0.1.6 // indirect github.com/gabriel-vasile/mimetype v1.4.8 // indirect - github.com/gin-contrib/sse v1.0.0 // indirect + github.com/gin-contrib/sse v1.1.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.26.0 // indirect + github.com/go-playground/validator/v10 v10.27.0 // indirect github.com/goccy/go-json v0.10.5 // indirect - github.com/golang-jwt/jwt/v5 v5.2.2 // indirect + github.com/goccy/go-yaml v1.18.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.10 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/pelletier/go-toml/v2 v2.2.3 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect + github.com/quic-go/qpack v0.5.1 // indirect + github.com/quic-go/quic-go v0.54.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.12 // indirect - golang.org/x/arch v0.15.0 // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/net v0.38.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect - google.golang.org/protobuf v1.36.6 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect + github.com/ugorji/go/codec v1.3.0 // indirect + go.uber.org/mock v0.5.0 // indirect + golang.org/x/arch v0.20.0 // indirect + golang.org/x/crypto v0.40.0 // indirect + golang.org/x/mod v0.25.0 // indirect + golang.org/x/net v0.42.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.35.0 // indirect + golang.org/x/text v0.27.0 // indirect + golang.org/x/tools v0.34.0 // indirect + google.golang.org/protobuf v1.36.9 // indirect ) -replace github.com/coinbase/x402/go => ../../../go +replace github.com/coinbase/x402-go/v2 => ../../../go diff --git a/e2e/servers/gin/go.sum b/e2e/servers/gin/go.sum index c185673bf..b9fcf82d0 100644 --- a/e2e/servers/gin/go.sum +++ b/e2e/servers/gin/go.sum @@ -1,49 +1,39 @@ -github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ= -github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= -github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= -github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= -github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= -github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= -github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= -github.com/coinbase/cdp-sdk/go v0.0.0-20250506223104-85d38372d771 h1:zFdgvx+jMCTkrOUTUD2Xmpk4vSusnpGqE90Gl37+WLQ= -github.com/coinbase/cdp-sdk/go v0.0.0-20250506223104-85d38372d771/go.mod h1:7SCUyseVQvmT158f23xvVghYF7dYxypj0sw+558F+7g= +github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ= +github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA= +github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= +github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= +github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= -github.com/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E= -github.com/gin-contrib/sse v1.0.0/go.mod h1:zNuFdwarAygJBht0NTKiSi3jRf6RbqeILZ9Sp6Slhe0= -github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= -github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= +github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= +github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k= -github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= +github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= +github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= -github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= -github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= +github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= -github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= -github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -53,47 +43,49 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= -github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= +github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= +github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg= +github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= -github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -golang.org/x/arch v0.15.0 h1:QtOrQd0bTUnhNVNndMpLHNWrDmYzZ2KDqSrEymqInZw= -golang.org/x/arch v0.15.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= +github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= +golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c= +golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= +golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= +golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= +golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo= +golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= +google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= +google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= diff --git a/e2e/servers/gin/main.go b/e2e/servers/gin/main.go index 98c82cd69..1e66f78cf 100644 --- a/e2e/servers/gin/main.go +++ b/e2e/servers/gin/main.go @@ -2,22 +2,29 @@ package main import ( "fmt" - "math/big" "net/http" "os" "os/signal" "syscall" "time" - "github.com/coinbase/x402/go/pkg/coinbasefacilitator" - x402gin "github.com/coinbase/x402/go/pkg/gin" - "github.com/coinbase/x402/go/pkg/types" - "github.com/gin-gonic/gin" + x402 "github.com/coinbase/x402-go/v2" + x402http "github.com/coinbase/x402-go/v2/http" + "github.com/coinbase/x402-go/v2/http/gin" + "github.com/coinbase/x402-go/v2/mechanisms/evm" + ginfw "github.com/gin-gonic/gin" "github.com/joho/godotenv" ) var shutdownRequested bool +/** + * Gin E2E Test Server with x402 v2 Payment Middleware + * + * This server demonstrates how to integrate x402 v2 payment middleware + * with a Gin application for end-to-end testing. + */ + func main() { // Load .env file if it exists if err := godotenv.Load(); err != nil { @@ -25,89 +32,112 @@ func main() { } // Get configuration from environment - useCdpFacilitator := os.Getenv("USE_CDP_FACILITATOR") == "true" - network := os.Getenv("EVM_NETWORK") - if network == "" { - network = "base-sepolia" - } - address := os.Getenv("EVM_ADDRESS") port := os.Getenv("PORT") if port == "" { port = "4021" } - // CDP facilitator configuration - cdpAPIKeyID := os.Getenv("CDP_API_KEY_ID") - cdpAPIKeySecret := os.Getenv("CDP_API_KEY_SECRET") - - if address == "" { - fmt.Println("Error: Missing required environment variable ADDRESS") + payeeAddress := os.Getenv("EVM_ADDRESS") + if payeeAddress == "" { + fmt.Println("āŒ EVM_ADDRESS environment variable is required") os.Exit(1) } - // Validate CDP configuration if using CDP facilitator - if useCdpFacilitator && (cdpAPIKeyID == "" || cdpAPIKeySecret == "") { - fmt.Println("Error: CDP facilitator enabled but missing CDP_API_KEY_ID or CDP_API_KEY_SECRET") + facilitatorURL := os.Getenv("FACILITATOR_URL") + if facilitatorURL == "" { + fmt.Println("āŒ FACILITATOR_URL environment variable is required") os.Exit(1) } - // Create facilitator config if using CDP - var facilitatorConfig *types.FacilitatorConfig - if useCdpFacilitator { - facilitatorConfig = coinbasefacilitator.CreateFacilitatorConfig(cdpAPIKeyID, cdpAPIKeySecret) - } + // Network configuration + network := x402.Network("eip155:84532") // Base Sepolia + + fmt.Printf("Facilitator account: %s\n", maskPrivateKey(os.Getenv("EVM_PRIVATE_KEY"))) + fmt.Printf("Using remote facilitator at: %s\n", facilitatorURL) // Set Gin to release mode to reduce logs - gin.SetMode(gin.ReleaseMode) - r := gin.New() - r.Use(gin.Recovery()) - - // Protected endpoint that requires payment - r.GET("/protected", - x402gin.PaymentMiddleware( - big.NewFloat(0.001), // $0.001 USD - address, - x402gin.WithFacilitatorConfig(facilitatorConfig), - x402gin.WithDescription("Protected endpoint requiring payment"), - x402gin.WithResource("http://localhost:"+port+"/protected"), - x402gin.WithTestnet(network == "base-sepolia"), - ), - func(c *gin.Context) { - if shutdownRequested { - c.JSON(http.StatusServiceUnavailable, gin.H{ - "error": "Server shutting down", - }) - return - } - - c.JSON(http.StatusOK, gin.H{ - "message": "Access granted to protected resource", - "timestamp": "2024-01-01T00:00:00Z", - "data": gin.H{ - "resource": "premium_content", - "access_level": "paid", - }, - }) + ginfw.SetMode(ginfw.ReleaseMode) + r := ginfw.New() + r.Use(ginfw.Recovery()) + + // Create HTTP facilitator client + facilitatorClient := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{ + URL: facilitatorURL, + }) + + /** + * Configure x402 payment middleware + * + * This middleware protects the /protected endpoint with a $0.001 USDC payment requirement + * on the Base Sepolia testnet. + */ + routes := x402http.RoutesConfig{ + "GET /protected": { + Scheme: "exact", + PayTo: payeeAddress, + Price: "$0.001", + Network: network, }, - ) - - // Health check endpoint - r.GET("/health", func(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{ - "status": "healthy", - "timestamp": "2024-01-01T00:00:00Z", - "server": "gin", + } + + // Create EVM service for handling exact payments + evmService := evm.NewExactEvmService() + + // Apply payment middleware + r.Use(gin.PaymentMiddleware( + routes, + gin.WithFacilitatorClient(facilitatorClient), + gin.WithScheme(network, evmService), + gin.WithInitializeOnStart(true), + gin.WithTimeout(30*time.Second), + )) + + /** + * Protected endpoint - requires payment to access + * + * This endpoint demonstrates a resource protected by x402 payment middleware. + * Clients must provide a valid payment signature to access this endpoint. + */ + r.GET("/protected", func(c *ginfw.Context) { + if shutdownRequested { + c.JSON(http.StatusServiceUnavailable, ginfw.H{ + "error": "Server shutting down", + }) + return + } + + c.JSON(http.StatusOK, ginfw.H{ + "message": "Protected endpoint accessed successfully", + "timestamp": time.Now().Format(time.RFC3339), + }) + }) + + /** + * Health check endpoint - no payment required + * + * Used to verify the server is running and responsive. + */ + r.GET("/health", func(c *ginfw.Context) { + c.JSON(http.StatusOK, ginfw.H{ + "status": "ok", + "network": string(network), + "payee": payeeAddress, + "version": "2.0.0", }) }) - // Graceful shutdown endpoint - r.POST("/close", func(c *gin.Context) { + /** + * Shutdown endpoint - used by e2e tests + * + * Allows graceful shutdown of the server during testing. + */ + r.POST("/close", func(c *ginfw.Context) { shutdownRequested = true - c.JSON(http.StatusOK, gin.H{ - "message": "Server shutting down gracefully", - "timestamp": "2024-01-01T00:00:00Z", + c.JSON(http.StatusOK, ginfw.H{ + "message": "Server shutting down gracefully", }) + fmt.Println("Received shutdown request") // Schedule server shutdown after response go func() { @@ -126,11 +156,21 @@ func main() { os.Exit(0) }() - fmt.Printf("Starting Gin server on port %s\n", port) - fmt.Printf("Server address: %s\n", address) - fmt.Printf("Network: %s\n", network) - fmt.Printf("Using CDP facilitator: %t\n", useCdpFacilitator) - fmt.Printf("Server listening on port %s\n", port) + // Print startup banner + fmt.Printf(` +╔════════════════════════════════════════════════════════╗ +ā•‘ x402 Gin E2E Test Server ā•‘ +╠════════════════════════════════════════════════════════╣ +ā•‘ Server: http://localhost:%s ā•‘ +ā•‘ Network: %s ā•‘ +ā•‘ Payee: %s ā•‘ +ā•‘ ā•‘ +ā•‘ Endpoints: ā•‘ +ā•‘ • GET /protected (requires $0.001 USDC payment) ā•‘ +ā•‘ • GET /health (no payment required) ā•‘ +ā•‘ • POST /close (shutdown server) ā•‘ +ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā• +`, port, network, payeeAddress) server := &http.Server{ Addr: ":" + port, @@ -142,3 +182,13 @@ func main() { os.Exit(1) } } + +func maskPrivateKey(key string) string { + if key == "" { + return "not configured" + } + if len(key) > 10 { + return key[:10] + "..." + } + return key +} diff --git a/e2e/servers/gin/run.sh b/e2e/servers/gin/run.sh old mode 100644 new mode 100755 index 00637611b..2532f0aff --- a/e2e/servers/gin/run.sh +++ b/e2e/servers/gin/run.sh @@ -1,2 +1,3 @@ #!/bin/bash -go run main.go \ No newline at end of file +go run main.go + diff --git a/e2e/servers/gin/test.config.json b/e2e/servers/gin/test.config.json index 58acb75c6..8ac008673 100644 --- a/e2e/servers/gin/test.config.json +++ b/e2e/servers/gin/test.config.json @@ -2,7 +2,8 @@ "name": "gin", "type": "server", "language": "go", - "description": "Go Gin server with x402 payment middleware", + "x402Version": 2, + "description": "Go Gin server with x402 v2 payment middleware", "endpoints": [ { "path": "/protected", @@ -26,14 +27,10 @@ ], "environment": { "required": [ - "EVM_ADDRESS" - ], - "optional": [ "PORT", - "USE_CDP_FACILITATOR", - "EVM_NETWORK", - "CDP_API_KEY_ID", - "CDP_API_KEY_SECRET" - ] + "EVM_ADDRESS", + "FACILITATOR_URL" + ], + "optional": [] } } \ No newline at end of file diff --git a/e2e/servers/text-server-protocol.txt b/e2e/servers/text-server-protocol.txt index f76586592..9b6569b0a 100644 --- a/e2e/servers/text-server-protocol.txt +++ b/e2e/servers/text-server-protocol.txt @@ -10,12 +10,22 @@ Servers must declare which protocol family each payment endpoint requires in the - **EVM**: Ethereum Virtual Machine compatible networks (Base, Ethereum, etc.) - **SVM**: Solana Virtual Machine compatible networks (Solana, etc.) +## X402 Version Support +Servers must declare which x402 protocol version they implement using the `x402Version` field: +- **x402Version**: The x402 protocol version implemented by the server (e.g., 1 or 2) + +## Extensions Support +Servers may declare which protocol extensions they support using the `extensions` field: +- **extensions**: Array of supported extension names (e.g., ["bazaar"]) + Example configuration: ```json { "name": "my-server", "type": "server", "language": "typescript", + "x402Version": 2, + "extensions": ["bazaar"], "endpoints": [ { "path": "/protected", @@ -39,7 +49,8 @@ Multi-protocol server example: { "name": "universal-server", "type": "server", - "language": "typescript", + "language": "typescript", + "x402Version": 2, "endpoints": [ { "path": "/evm-protected", diff --git a/e2e/src/clients/generic-client.ts b/e2e/src/clients/generic-client.ts index 07cb553ed..6a5b050c2 100644 --- a/e2e/src/clients/generic-client.ts +++ b/e2e/src/clients/generic-client.ts @@ -23,7 +23,7 @@ export class GenericClientProxy extends BaseProxy implements ClientProxy { EVM_PRIVATE_KEY: config.evmPrivateKey, SVM_PRIVATE_KEY: config.svmPrivateKey, RESOURCE_SERVER_URL: config.serverUrl, - ENDPOINT_PATH: config.endpointPath + ENDPOINT_PATH: config.endpointPath, } }; diff --git a/e2e/src/discovery.ts b/e2e/src/discovery.ts index 0fcecdf8b..f63e32044 100644 --- a/e2e/src/discovery.ts +++ b/e2e/src/discovery.ts @@ -2,29 +2,33 @@ import { readdirSync, readFileSync, existsSync } from 'fs'; import { join } from 'path'; import { GenericServerProxy } from './servers/generic-server'; import { GenericClientProxy } from './clients/generic-client'; +import { GenericFacilitatorProxy } from './facilitators/generic-facilitator'; import { log, verboseLog, errorLog } from './logger'; import { TestConfig, DiscoveredServer, DiscoveredClient, + DiscoveredFacilitator, TestScenario, ProtocolFamily } from './types'; -const facilitatorNetworkCombos = [ - { useCdpFacilitator: false, network: 'base-sepolia', protocolFamily: 'evm' as ProtocolFamily }, - { useCdpFacilitator: true, network: 'base-sepolia', protocolFamily: 'evm' as ProtocolFamily }, - { useCdpFacilitator: true, network: 'base', protocolFamily: 'evm' as ProtocolFamily }, - { useCdpFacilitator: false, network: 'solana-devnet', protocolFamily: 'svm' as ProtocolFamily }, - { useCdpFacilitator: true, network: 'solana-devnet', protocolFamily: 'svm' as ProtocolFamily }, - { useCdpFacilitator: true, network: 'solana', protocolFamily: 'svm' as ProtocolFamily } -]; +// Will be populated with discovered facilitators +let facilitatorNetworkCombos: Array<{ + useCdpFacilitator: boolean; + network: string; + protocolFamily: ProtocolFamily; + x402Version: number; + facilitatorName?: string; +}> = []; export class TestDiscovery { private baseDir: string; + private includeLegacy: boolean; - constructor(baseDir: string = '.') { + constructor(baseDir: string = '.', includeLegacy: boolean = false) { this.baseDir = baseDir; + this.includeLegacy = includeLegacy; } getFacilitatorNetworkCombos(): typeof facilitatorNetworkCombos { @@ -56,12 +60,29 @@ export class TestDiscovery { * Discover all servers in the servers directory */ discoverServers(): DiscoveredServer[] { + const servers: DiscoveredServer[] = []; + + // Discover servers from main servers directory const serversDir = join(this.baseDir, 'servers'); - if (!existsSync(serversDir)) { - return []; + if (existsSync(serversDir)) { + this.discoverServersInDirectory(serversDir, servers); } - const servers: DiscoveredServer[] = []; + // Discover servers from legacy directory if flag is set + if (this.includeLegacy) { + const legacyServersDir = join(this.baseDir, 'legacy', 'servers'); + if (existsSync(legacyServersDir)) { + this.discoverServersInDirectory(legacyServersDir, servers, 'legacy-'); + } + } + + return servers; + } + + /** + * Helper method to discover servers in a specific directory + */ + private discoverServersInDirectory(serversDir: string, servers: DiscoveredServer[], namePrefix: string = ''): void { let serverDirs = readdirSync(serversDir, { withFileTypes: true }) .filter(dirent => dirent.isDirectory()) .map(dirent => dirent.name); @@ -77,31 +98,101 @@ export class TestDiscovery { if (config.type === 'server') { servers.push({ - name: serverName, + name: namePrefix + serverName, directory: serverDir, config, proxy: new GenericServerProxy(serverDir) }); } } catch (error) { - errorLog(`Failed to load config for server ${serverName}: ${error}`); + errorLog(`Failed to load config for server ${namePrefix}${serverName}: ${error}`); } } } - - return servers; } /** * Discover all clients in the clients directory */ discoverClients(): DiscoveredClient[] { + const clients: DiscoveredClient[] = []; + + // Discover clients from main clients directory const clientsDir = join(this.baseDir, 'clients'); - if (!existsSync(clientsDir)) { - return []; + if (existsSync(clientsDir)) { + this.discoverClientsInDirectory(clientsDir, clients); } - const clients: DiscoveredClient[] = []; + // Discover clients from legacy directory if flag is set + if (this.includeLegacy) { + const legacyClientsDir = join(this.baseDir, 'legacy', 'clients'); + if (existsSync(legacyClientsDir)) { + this.discoverClientsInDirectory(legacyClientsDir, clients, 'legacy-'); + } + } + + return clients; + } + + /** + * Discover all facilitators in the facilitators directory + */ + discoverFacilitators(): DiscoveredFacilitator[] { + const facilitators: DiscoveredFacilitator[] = []; + + // Discover facilitators from main facilitators directory + const facilitatorsDir = join(this.baseDir, 'facilitators'); + if (existsSync(facilitatorsDir)) { + this.discoverFacilitatorsInDirectory(facilitatorsDir, facilitators); + } + + // Discover facilitators from legacy directory if flag is set + if (this.includeLegacy) { + const legacyFacilitatorsDir = join(this.baseDir, 'legacy', 'facilitators'); + if (existsSync(legacyFacilitatorsDir)) { + this.discoverFacilitatorsInDirectory(legacyFacilitatorsDir, facilitators, 'legacy-'); + } + } + + return facilitators; + } + + /** + * Helper method to discover facilitators in a specific directory + */ + private discoverFacilitatorsInDirectory(facilitatorsDir: string, facilitators: DiscoveredFacilitator[], namePrefix: string = ''): void { + let facilitatorDirs = readdirSync(facilitatorsDir, { withFileTypes: true }) + .filter(dirent => dirent.isDirectory()) + .map(dirent => dirent.name); + + for (const facilitatorName of facilitatorDirs) { + const facilitatorDir = join(facilitatorsDir, facilitatorName); + const configPath = join(facilitatorDir, 'test.config.json'); + + if (existsSync(configPath)) { + try { + const configContent = readFileSync(configPath, 'utf-8'); + const config: TestConfig = JSON.parse(configContent); + + if (config.type === 'facilitator') { + facilitators.push({ + name: namePrefix + facilitatorName, + directory: facilitatorDir, + config, + proxy: new GenericFacilitatorProxy(facilitatorDir) + }); + } + } catch (error) { + errorLog(`Failed to load config for facilitator ${namePrefix}${facilitatorName}: ${error}`); + } + } + } + } + + /** + * Helper method to discover clients in a specific directory + */ + private discoverClientsInDirectory(clientsDir: string, clients: DiscoveredClient[], namePrefix: string = ''): void { let clientDirs = readdirSync(clientsDir, { withFileTypes: true }) .filter(dirent => dirent.isDirectory()) .map(dirent => dirent.name); @@ -117,19 +208,62 @@ export class TestDiscovery { if (config.type === 'client') { clients.push({ - name: clientName, + name: namePrefix + clientName, directory: clientDir, config, proxy: new GenericClientProxy(clientDir) }); } } catch (error) { - errorLog(`Failed to load config for client ${clientName}: ${error}`); + errorLog(`Failed to load config for client ${namePrefix}${clientName}: ${error}`); } } } + } - return clients; + /** + * Build facilitator network combos from discovered facilitators + */ + private buildFacilitatorNetworkCombos(facilitators: DiscoveredFacilitator[]): void { + facilitatorNetworkCombos = []; + + for (const facilitator of facilitators) { + const protocolFamilies = facilitator.config.protocolFamilies || ['evm']; + const x402Versions = facilitator.config.x402Versions || [2]; + + for (const protocolFamily of protocolFamilies) { + for (const x402Version of x402Versions) { + // Add network combos based on protocol family + if (protocolFamily === 'evm') { + facilitatorNetworkCombos.push({ + useCdpFacilitator: false, + network: 'eip155:84532', + protocolFamily: protocolFamily as ProtocolFamily, + x402Version, + facilitatorName: facilitator.name + }); + } else if (protocolFamily === 'svm') { + facilitatorNetworkCombos.push({ + useCdpFacilitator: false, + network: 'solana:devnet', + protocolFamily: protocolFamily as ProtocolFamily, + x402Version, + facilitatorName: facilitator.name + }); + } + } + } + } + + // If no facilitators found, add a default combo for backward compatibility + if (facilitatorNetworkCombos.length === 0) { + facilitatorNetworkCombos.push({ + useCdpFacilitator: false, + network: 'eip155:84532', + protocolFamily: 'evm', + x402Version: 2 + }); + } } /** @@ -138,13 +272,39 @@ export class TestDiscovery { generateTestScenarios(): TestScenario[] { const servers = this.discoverServers(); const clients = this.discoverClients(); + const facilitators = this.discoverFacilitators(); + + // Build facilitator network combos from discovered facilitators + this.buildFacilitatorNetworkCombos(facilitators); + const scenarios: TestScenario[] = []; for (const client of clients) { // Default to EVM if no protocol families specified for backward compatibility const clientProtocolFamilies = client.config.protocolFamilies || ['evm']; + // Get client's supported x402 versions (default to [1] for backward compatibility) + const clientVersions = client.config.x402Versions; + if (!clientVersions) { + errorLog(` āš ļø Skipping ${client.name}: No x402 versions specified`); + continue; + } + for (const server of servers) { + // Get server's x402 version (default to 1 for backward compatibility) + const serverVersion = server.config.x402Version; + if (!serverVersion) { + errorLog(` āš ļø Skipping ${server.name}: No x402 version specified`); + continue; + } + + // Check if client and server have compatible versions + if (!clientVersions.includes(serverVersion)) { + // Skip this client-server pair if versions don't overlap + verboseLog(` āš ļø Skipping ${client.name} ↔ ${server.name}: Version mismatch (client supports [${clientVersions.join(', ')}], server implements ${serverVersion})`); + continue; + } + // Only test endpoints that require payment const testableEndpoints = server.config.endpoints?.filter(endpoint => { // Only include endpoints that require payment @@ -161,9 +321,15 @@ export class TestDiscovery { const combosForProtocol = this.getFacilitatorNetworkCombosForProtocol(endpointProtocolFamily); for (const combo of combosForProtocol) { + // Find matching facilitator if specified + const matchingFacilitator = combo.facilitatorName + ? facilitators.find(f => f.name === combo.facilitatorName) + : undefined; + scenarios.push({ client, server, + facilitator: matchingFacilitator, endpoint, protocolFamily: endpointProtocolFamily, facilitatorNetworkCombo: { @@ -186,23 +352,39 @@ export class TestDiscovery { printDiscoverySummary(): void { const servers = this.discoverServers(); const clients = this.discoverClients(); + const facilitators = this.discoverFacilitators(); + + // Build combos to get accurate scenario count + this.buildFacilitatorNetworkCombos(facilitators); const scenarios = this.generateTestScenarios(); log('šŸ” Test Discovery Summary'); log('========================'); + if (this.includeLegacy) { + log('šŸ”„ Legacy mode enabled - including legacy implementations'); + } log(`šŸ“” Servers found: ${servers.length}`); servers.forEach(server => { const paidEndpoints = server.config.endpoints?.filter(e => e.requiresPayment).length || 0; const protocolFamilies = new Set( server.config.endpoints?.filter(e => e.requiresPayment).map(e => e.protocolFamily || 'evm') || ['evm'] ); - log(` - ${server.name} (${server.config.language}) - ${paidEndpoints} x402 endpoints [${Array.from(protocolFamilies).join(', ')}]`); + const version = server.config.x402Version || 1; + log(` - ${server.name} (${server.config.language}) v${version} - ${paidEndpoints} x402 endpoints [${Array.from(protocolFamilies).join(', ')}]`); }); log(`šŸ“± Clients found: ${clients.length}`); clients.forEach(client => { const protocolFamilies = client.config.protocolFamilies || ['evm']; - log(` - ${client.name} (${client.config.language}) [${protocolFamilies.join(', ')}]`); + const versions = client.config.x402Versions || [1]; + log(` - ${client.name} (${client.config.language}) v[${versions.join(', ')}] [${protocolFamilies.join(', ')}]`); + }); + + log(`šŸ›ļø Facilitators found: ${facilitators.length}`); + facilitators.forEach(facilitator => { + const protocolFamilies = facilitator.config.protocolFamilies || ['evm']; + const versions = facilitator.config.x402Versions || [2]; + log(` - ${facilitator.name} (${facilitator.config.language}) v[${versions.join(', ')}] [${protocolFamilies.join(', ')}]`); }); log(`šŸ”§ Facilitator/Network combos: ${this.getFacilitatorNetworkCombos().length}`); diff --git a/e2e/src/facilitators/generic-facilitator.ts b/e2e/src/facilitators/generic-facilitator.ts new file mode 100644 index 000000000..0f0dbbb43 --- /dev/null +++ b/e2e/src/facilitators/generic-facilitator.ts @@ -0,0 +1,297 @@ +import { BaseProxy, RunConfig } from '../proxy-base'; +import { verboseLog, errorLog } from '../logger'; + +export interface VerifyRequest { + x402Version: number; + paymentPayload: any; + paymentRequirements: any; +} + +export interface VerifyResponse { + isValid: boolean; + invalidReason?: string; + payer?: string; +} + +export interface SettleRequest { + x402Version: number; + paymentPayload: any; + paymentRequirements: any; +} + +export interface SettleResponse { + success: boolean; + transaction?: string; + errorReason?: string; + network?: string; + payer?: string; +} + +export interface SupportedResponse { + kinds: Array<{ + x402Version: number; + scheme: string; + network: string; + extra?: Record; + }>; + extensions: any[]; +} + +export interface HealthResponse { + status: string; +} + +export interface FacilitatorResult { + success: boolean; + data?: T; + error?: string; + statusCode?: number; +} + +export interface FacilitatorConfig { + port: number; + evmPrivateKey?: string; + svmPrivateKey?: string; + evmNetwork?: string; + svmNetwork?: string; +} + +export interface FacilitatorProxy { + start(config: FacilitatorConfig): Promise; + stop(): Promise; + verify(request: VerifyRequest): Promise>; + settle(request: SettleRequest): Promise>; + getSupported(): Promise>; + health(): Promise>; + getUrl(): string; +} + +export class GenericFacilitatorProxy extends BaseProxy implements FacilitatorProxy { + private port: number = 4022; + private healthEndpoint: string = '/health'; + private closeEndpoint: string = '/close'; + + constructor(directory: string) { + // Facilitators should log when ready + super(directory, 'Facilitator listening'); + this.loadEndpoints(); + } + + private loadEndpoints(): void { + try { + const { readFileSync, existsSync } = require('fs'); + const { join } = require('path'); + const configPath = join(this.directory, 'test.config.json'); + + if (existsSync(configPath)) { + const configContent = readFileSync(configPath, 'utf-8'); + const config = JSON.parse(configContent); + + // Load health endpoint if specified + const healthEndpoint = config.endpoints?.find((endpoint: any) => endpoint.health); + if (healthEndpoint) { + this.healthEndpoint = healthEndpoint.path; + } + + // Load close endpoint if specified + const closeEndpoint = config.endpoints?.find((endpoint: any) => endpoint.close); + if (closeEndpoint) { + this.closeEndpoint = closeEndpoint.path; + } + } + } catch (error) { + // Fallback to defaults if config loading fails + errorLog(`Failed to load endpoints from config for ${this.directory}, using defaults`); + } + } + + async start(config: FacilitatorConfig): Promise { + this.port = config.port; + + const runConfig: RunConfig = { + port: config.port, + env: { + PORT: config.port.toString(), + EVM_PRIVATE_KEY: config.evmPrivateKey || '', + SVM_PRIVATE_KEY: config.svmPrivateKey || '', + EVM_NETWORK: config.evmNetwork || 'eip155:84532', + SVM_NETWORK: config.svmNetwork || 'solana:devnet', + EVM_RPC_URL: process.env.BASE_SEPOLIA_RPC_URL || process.env.EVM_RPC_URL || '', + } + }; + + await this.startProcess(runConfig); + } + + async verify(request: VerifyRequest): Promise> { + try { + const response = await fetch(`http://localhost:${this.port}/verify`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(request), + }); + + if (!response.ok) { + return { + success: false, + error: `Verify failed: ${response.status} ${response.statusText}`, + statusCode: response.status + }; + } + + const data = await response.json(); + return { + success: true, + data: data as VerifyResponse, + statusCode: response.status + }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : String(error) + }; + } + } + + async settle(request: SettleRequest): Promise> { + try { + const response = await fetch(`http://localhost:${this.port}/settle`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(request), + }); + + if (!response.ok) { + return { + success: false, + error: `Settle failed: ${response.status} ${response.statusText}`, + statusCode: response.status + }; + } + + const data = await response.json(); + return { + success: true, + data: data as SettleResponse, + statusCode: response.status + }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : String(error) + }; + } + } + + async getSupported(): Promise> { + try { + const response = await fetch(`http://localhost:${this.port}/supported`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }); + + if (!response.ok) { + return { + success: false, + error: `Get supported failed: ${response.status} ${response.statusText}`, + statusCode: response.status + }; + } + + const data = await response.json(); + return { + success: true, + data: data as SupportedResponse, + statusCode: response.status + }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : String(error) + }; + } + } + + async health(): Promise> { + try { + const response = await fetch(`http://localhost:${this.port}${this.healthEndpoint}`); + + if (!response.ok) { + return { + success: false, + error: `Health check failed: ${response.status} ${response.statusText}`, + statusCode: response.status + }; + } + + const data = await response.json(); + return { + success: true, + data: data as HealthResponse, + statusCode: response.status + }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : String(error) + }; + } + } + + async close(): Promise> { + try { + const response = await fetch(`http://localhost:${this.port}${this.closeEndpoint}`, { + method: 'POST' + }); + + if (!response.ok) { + return { + success: false, + error: `Close failed: ${response.status} ${response.statusText}`, + statusCode: response.status + }; + } + + const data = await response.json(); + return { + success: true, + data: data as { message: string }, + statusCode: response.status + }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : String(error) + }; + } + } + + async stop(): Promise { + if (this.process) { + try { + // Try graceful shutdown via POST /close + const closeResult = await this.close(); + if (closeResult.success) { + // Wait a bit for graceful shutdown + await new Promise(resolve => setTimeout(resolve, 2000)); + } else { + verboseLog('Graceful shutdown failed, using force kill'); + } + } catch (error) { + verboseLog('Graceful shutdown failed, using force kill'); + } + } + + await this.stopProcess(); + } + + getUrl(): string { + return `http://localhost:${this.port}`; + } +} diff --git a/e2e/src/networks/networks.ts b/e2e/src/networks/networks.ts new file mode 100644 index 000000000..b8075e3a1 --- /dev/null +++ b/e2e/src/networks/networks.ts @@ -0,0 +1,41 @@ +type Network = { + name: string; + caip2: `${string}:${string}`; + v1Name?: string; + rpcUrl: string; +} + +export const NETWORKS = [ + { + name: 'Base Sepolia', + caip2: 'eip155:84532', + v1Name: 'base-sepolia', + rpcUrl: process.env.BASE_SEPOLIA_RPC_URL || 'https://sepolia.base.org', + }, + { + name: "Solana Devnet", + caip2: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1', + v1Name: 'solana-devnet', + rpcUrl: process.env.SOLANA_DEVNET_RPC_URL || 'https://api.devnet.solana.com', + }, + { + name: 'Base', + caip2: 'eip155:8453', + v1Name: 'base', + rpcUrl: process.env.BASE_RPC_URL || 'https://mainnet.base.org', + }, + { + name: "Solana", + caip2: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp', + v1Name: 'solana-devnet', + rpcUrl: process.env.SOLANA_RPC_URL || 'https://api.mainnet-beta.solana.com', + }, +] satisfies Network[]; + +export const getNetwork = (network: string): Network | undefined => { + let result = NETWORKS.find(n => n.caip2 === network); + if (!result) { + result = NETWORKS.find(n => n.v1Name === network); + } + return result; +} \ No newline at end of file diff --git a/e2e/src/proxy-base.ts b/e2e/src/proxy-base.ts index 7ee1cc73b..ac904bd93 100644 --- a/e2e/src/proxy-base.ts +++ b/e2e/src/proxy-base.ts @@ -173,20 +173,28 @@ export abstract class BaseProxy { }); childProcess.on('close', (code: number | null) => { - if (code === 0) { - try { - // Find JSON result in stdout - const lines = stdout.split('\n'); - const jsonLine = lines.find(line => line.trim().startsWith('{')); - if (jsonLine) { - const result = JSON.parse(jsonLine); + // Try to find JSON in stdout regardless of exit code + try { + const lines = stdout.split('\n'); + const jsonLine = lines.find(line => line.trim().startsWith('{')); + if (jsonLine) { + const result = JSON.parse(jsonLine); + if (code === 0) { resolve({ success: true, data: result, exitCode: code }); } else { - resolve({ success: false, error: 'No JSON result found', exitCode: code }); + // Non-zero exit but we have JSON error details + const errorMsg = result.error || `Process exited with code ${code}`; + resolve({ success: false, error: errorMsg, exitCode: code || undefined }); } - } catch (error) { - resolve({ success: false, error: `Failed to parse result: ${error}`, exitCode: code }); + return; } + } catch (error) { + // Failed to parse JSON, fall through to default error handling + } + + // No JSON found or parse failed + if (code === 0) { + resolve({ success: false, error: 'No JSON result found', exitCode: code }); } else { resolve({ success: false, error: stderr || `Process exited with code ${code}`, exitCode: code || undefined }); } diff --git a/e2e/src/servers/generic-server.ts b/e2e/src/servers/generic-server.ts index a4d665343..e7ec55573 100644 --- a/e2e/src/servers/generic-server.ts +++ b/e2e/src/servers/generic-server.ts @@ -1,6 +1,33 @@ import { BaseProxy, RunConfig } from '../proxy-base'; -import { ServerProxy, ServerConfig } from '../types'; +import { ServerProxy } from '../types'; import { verboseLog, errorLog } from '../logger'; +import { getNetwork } from '../networks/networks'; + +/** + * Translates v2 CAIP-2 network format to v1 simple format for legacy servers + * + * @param network - Network in CAIP-2 format (e.g., "eip155:84532") + * @returns Network in v1 format (e.g., "base-sepolia") + */ +function translateNetworkForV1(network: string): string { + const networkMap: Record = { + 'eip155:84532': 'base-sepolia', + 'eip155:8453': 'base', + 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1': 'solana-devnet', + 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp': 'solana-mainnet', + }; + + return networkMap[network] || network; +} + +interface ServerConfig { + port: number; + evmPayTo: string; + svmPayTo: string; + evmNetwork: string; + svmNetwork: string; + facilitatorUrl?: string; +} export interface ProtectedResponse { message: string; @@ -67,17 +94,43 @@ export class GenericServerProxy extends BaseProxy implements ServerProxy { async start(config: ServerConfig): Promise { this.port = config.port; + // Check if this is a v1 (legacy) server based on directory name + const isV1Server = this.directory.includes('legacy/'); + + verboseLog(` šŸ“‚ Server directory: ${this.directory}, isV1: ${isV1Server}`); + + // Translate networks to v1 format for legacy servers using getNetwork helper + let evmNetwork = config.evmNetwork; + let svmNetwork = config.svmNetwork; + + if (isV1Server) { + // Use getNetwork to look up and get v1 name + const evmNetworkInfo = getNetwork(config.evmNetwork); + const svmNetworkInfo = getNetwork(config.svmNetwork); + + evmNetwork = evmNetworkInfo?.v1Name || translateNetworkForV1(config.evmNetwork); + svmNetwork = svmNetworkInfo?.v1Name || translateNetworkForV1(config.svmNetwork); + + verboseLog(` šŸ”„ Translating networks for v1 server: ${config.evmNetwork} → ${evmNetwork}, ${config.svmNetwork} → ${svmNetwork}`); + } + const runConfig: RunConfig = { port: config.port, env: { - USE_CDP_FACILITATOR: config.useCdpFacilitator.toString(), - CDP_API_KEY_ID: process.env.CDP_API_KEY_ID || '', - CDP_API_KEY_SECRET: process.env.CDP_API_KEY_SECRET || '', - EVM_NETWORK: config.evmNetwork, + EVM_NETWORK: evmNetwork, EVM_ADDRESS: config.evmPayTo, - SVM_NETWORK: config.svmNetwork, + SVM_NETWORK: svmNetwork, SVM_ADDRESS: config.svmPayTo, - PORT: config.port.toString() + PORT: config.port.toString(), + EVM_RPC_URL: getNetwork(config.evmNetwork)?.rpcUrl || '', + + // Use facilitator URL if provided + FACILITATOR_URL: config.facilitatorUrl || '', + + // TODO: Include private keys for servers temporarily until we have a facilitator for e2e tests to call directly. Until then, they act as their own facilitator + EVM_PRIVATE_KEY: process.env.CLIENT_EVM_PRIVATE_KEY || '', + SVM_PRIVATE_KEY: process.env.CLIENT_SVM_PRIVATE_KEY || '', + } }; diff --git a/e2e/src/types.ts b/e2e/src/types.ts index 4f10f0e04..609be6278 100644 --- a/e2e/src/types.ts +++ b/e2e/src/types.ts @@ -8,20 +8,20 @@ export interface ClientResult { error?: string; } +export interface ClientConfig { + evmPrivateKey: string; + svmPrivateKey: string; + serverUrl: string; + endpointPath: string; +} + export interface ServerConfig { port: number; - useCdpFacilitator: boolean; evmPayTo: string; svmPayTo: string; evmNetwork: string; svmNetwork: string; -} - -export interface ClientConfig { - evmPrivateKey: string; - svmPrivateKey: string; - serverUrl: string; - endpointPath: string; + facilitatorUrl?: string; } export interface ServerProxy { @@ -50,9 +50,12 @@ export interface TestEndpoint { export interface TestConfig { name: string; - type: 'server' | 'client'; + type: 'server' | 'client' | 'facilitator'; language: string; protocolFamilies?: ProtocolFamily[]; + x402Version?: number; // For servers - single version they implement + x402Versions?: number[]; // For clients and facilitators - array of versions they support + extensions?: string[]; // Protocol extensions supported (e.g., ["bazaar"]) endpoints?: TestEndpoint[]; supportedMethods?: string[]; capabilities?: { @@ -79,14 +82,29 @@ export interface DiscoveredClient { proxy: ClientProxy; } +export interface FacilitatorProxy { + start(config: any): Promise; + stop(): Promise; + getUrl(): string; +} + +export interface DiscoveredFacilitator { + name: string; + directory: string; + config: TestConfig; + proxy: FacilitatorProxy; +} + export interface TestScenario { client: DiscoveredClient; server: DiscoveredServer; + facilitator?: DiscoveredFacilitator; endpoint: TestEndpoint; protocolFamily: ProtocolFamily; facilitatorNetworkCombo: { useCdpFacilitator: boolean; network: string; + facilitatorUrl?: string; }; } diff --git a/e2e/test.ts b/e2e/test.ts index 0feb99fac..ced83d64a 100644 --- a/e2e/test.ts +++ b/e2e/test.ts @@ -1,7 +1,17 @@ import { config } from 'dotenv'; import { TestDiscovery } from './src/discovery'; -import { ServerConfig, ClientConfig, ScenarioResult } from './src/types'; +import { ClientConfig, ScenarioResult } from './src/types'; import { config as loggerConfig, log, verboseLog, errorLog, close as closeLogger } from './src/logger'; +import { handleDiscoveryValidation, shouldRunDiscoveryValidation } from './extensions/bazaar'; + +export interface ServerConfig { + port: number; + evmPayTo: string; + svmPayTo: string; + evmNetwork: string; + svmNetwork: string; + facilitatorUrl?: string; +} // Load environment variables config(); @@ -9,12 +19,12 @@ config(); // Parse command line arguments const args = process.argv.slice(2); -// Parse dev mode flag (sets network=base-sepolia, prod=false) -const isDevMode = args.includes('--dev') || args.includes('-d'); - // Parse verbose flag const isVerbose = args.includes('-v') || args.includes('--verbose'); +// Parse legacy flag (includes /legacy directory in discovery) +const includeLegacy = args.includes('--legacy'); + // Parse language flags const languageFilters: string[] = []; if (args.includes('-ts') || args.includes('--typescript')) languageFilters.push('typescript'); @@ -34,11 +44,6 @@ args.forEach((arg, index) => { // Parse filter arguments const clientFilter = args.find(arg => arg.startsWith('--client='))?.split('=')[1]; const serverFilter = args.find(arg => arg.startsWith('--server='))?.split('=')[1]; -const networkFilter = isDevMode ? ['base-sepolia', 'solana-devnet'] : - args.find(arg => arg.startsWith('--network='))?.split('=')[1] ? - [args.find(arg => arg.startsWith('--network='))?.split('=')[1]!] : - undefined; -const prodFilter = isDevMode ? 'false' : args.find(arg => arg.startsWith('--prod='))?.split('=')[1]; // Parse log file argument const logFile = args.find(arg => arg.startsWith('--log-file='))?.split('=')[1]; @@ -46,70 +51,197 @@ const logFile = args.find(arg => arg.startsWith('--log-file='))?.split('=')[1]; // Initialize logger loggerConfig({ logFile, verbose: isVerbose }); -async function runCallProtectedScenario( - server: any, - client: any, - serverConfig: ServerConfig, - callConfig: ClientConfig -): Promise { - try { - verboseLog(` šŸš€ Starting server with config: ${JSON.stringify(serverConfig, null, 2)}`); - await server.start(serverConfig); +interface Facilitator { + start: (config: { port: number; evmPrivateKey: string; svmPrivateKey: string; evmNetwork: string; svmNetwork: string; }) => Promise; + health: () => Promise<{ success: boolean }>; + getUrl: () => string; + stop: () => Promise; +} - // Wait for server to be healthy before proceeding - let healthCheckAttempts = 0; - const maxHealthCheckAttempts = 10; +// FacilitatorManager handles async facilitator lifecycle +class FacilitatorManager { + private facilitator: any; + private port: number; + private readyPromise: Promise; + private url: string | null = null; - while (healthCheckAttempts < maxHealthCheckAttempts) { - const healthResult = await server.health(); - verboseLog(` šŸ” Health check attempt ${healthCheckAttempts + 1}/${maxHealthCheckAttempts}: ${healthResult.success ? 'āœ…' : 'āŒ'}`); + constructor(facilitator: Facilitator, port: number, evmNetwork: string, svmNetwork: string) { + this.facilitator = facilitator; + this.port = port; + + // Start facilitator and health checks asynchronously + this.readyPromise = this.startAndWaitForHealth(evmNetwork, svmNetwork); + } + + private async startAndWaitForHealth(evmNetwork: string, svmNetwork: string): Promise { + verboseLog(` šŸ›ļø Starting facilitator on port ${this.port}...`); + + await this.facilitator.start({ + port: this.port, + evmPrivateKey: process.env.CLIENT_EVM_PRIVATE_KEY, + svmPrivateKey: process.env.CLIENT_SVM_PRIVATE_KEY, + evmNetwork, + svmNetwork, + }); + + // Wait for facilitator to be healthy + let attempts = 0; + const maxAttempts = 10; + + while (attempts < maxAttempts) { + const healthResult = await this.facilitator.health(); + verboseLog(` šŸ” Facilitator health check ${attempts + 1}/${maxAttempts}: ${healthResult.success ? 'āœ…' : 'āŒ'}`); if (healthResult.success) { - verboseLog(` āœ… Server is healthy after ${healthCheckAttempts + 1} attempts`); - break; + verboseLog(` āœ… Facilitator is healthy`); + this.url = this.facilitator.getUrl(); + return this.url; } - healthCheckAttempts++; + attempts++; await new Promise(resolve => setTimeout(resolve, 2000)); } - if (healthCheckAttempts >= maxHealthCheckAttempts) { - verboseLog(` āŒ Server failed to become healthy after ${maxHealthCheckAttempts} attempts`); - return { - success: false, - error: 'Server failed to become healthy after maximum attempts' - }; + verboseLog(` āŒ Facilitator failed to become healthy`); + return null; + } + + async ready(): Promise { + return this.readyPromise; + } + + getProxy(): any { + return this.facilitator; + } + + async stop(): Promise { + if (this.facilitator) { + await this.facilitator.stop(); } + } +} - verboseLog(` šŸ“ž Making client call with config: ${JSON.stringify(callConfig, null, 2)}`); - const result = await client.call(callConfig); +async function startServer( + server: any, + serverConfig: ServerConfig +): Promise { + verboseLog(` šŸš€ Starting server on port ${serverConfig.port}...`); + await server.start(serverConfig); + + // Wait for server to be healthy + let attempts = 0; + const maxAttempts = 10; + + while (attempts < maxAttempts) { + const healthResult = await server.health(); + verboseLog(` šŸ” Server health check ${attempts + 1}/${maxAttempts}: ${healthResult.success ? 'āœ…' : 'āŒ'}`); + + if (healthResult.success) { + verboseLog(` āœ… Server is healthy`); + return true; + } + + attempts++; + await new Promise(resolve => setTimeout(resolve, 2000)); + } - verboseLog(` šŸ“Š Client call result: ${JSON.stringify(result, null, 2)}`); + verboseLog(` āŒ Server failed to become healthy`); + return false; +} - if (result.success) { +async function runClientTest( + client: any, + callConfig: ClientConfig +): Promise { + const verboseLogs: string[] = []; + + const bufferLog = (msg: string) => { + verboseLogs.push(msg); + }; + + try { + bufferLog(` šŸ“ž Running client: ${JSON.stringify(callConfig, null, 2)}`); + const result = await client.call(callConfig); + bufferLog(` šŸ“Š Client result: ${JSON.stringify(result, null, 2)}`); + + // Check if the client execution succeeded + if (!result.success) { return { - success: true, - data: result.data, - status_code: result.status_code, - payment_response: result.payment_response + success: false, + error: result.error || 'Client execution failed', + verboseLogs }; - } else { + } + + // Check if we got a 402 Payment Required response (payment failed) + if (result.status_code === 402) { + const errorData = result.data as any; + const errorMsg = errorData?.error || 'Payment required - payment failed'; return { success: false, - error: result.error + error: `Payment failed (402): ${errorMsg}`, + data: result.data, + status_code: result.status_code, + verboseLogs }; } + // For protected endpoints, verify the payment actually succeeded + const paymentResponse = result.payment_response; + if (paymentResponse) { + // Payment was required - verify it succeeded + if (!paymentResponse.success) { + return { + success: false, + error: `Payment failed: ${paymentResponse.errorReason || 'unknown error'}`, + data: result.data, + status_code: result.status_code, + payment_response: paymentResponse, + verboseLogs + }; + } + + // Payment should have a transaction hash + if (!paymentResponse.transaction) { + return { + success: false, + error: 'Payment succeeded but no transaction hash returned', + data: result.data, + status_code: result.status_code, + payment_response: paymentResponse, + verboseLogs + }; + } + + // Payment should not have an error reason + if (paymentResponse.errorReason) { + return { + success: false, + error: `Payment has error reason: ${paymentResponse.errorReason}`, + data: result.data, + status_code: result.status_code, + payment_response: paymentResponse, + verboseLogs + }; + } + } + + // All checks passed + return { + success: true, + data: result.data, + status_code: result.status_code, + payment_response: paymentResponse, + verboseLogs + }; } catch (error) { - verboseLog(` šŸ’„ Scenario failed with error: ${error}`); + bufferLog(` šŸ’„ Client failed: ${error}`); return { success: false, - error: error instanceof Error ? error.message : String(error) + error: error instanceof Error ? error.message : String(error), + verboseLogs }; } finally { - // Cleanup - verboseLog(` 🧹 Cleaning up server and client processes`); - await server.stop(); await client.forceStop(); } } @@ -121,8 +253,8 @@ async function runTest() { console.log(''); console.log('Options:'); console.log('Environment:'); - console.log(' -d, --dev Development mode (base-sepolia, no CDP)'); console.log(' -v, --verbose Enable verbose logging'); + console.log(' --legacy Include legacy implementations from /legacy directory'); console.log(' -ts, --typescript Include TypeScript implementations'); console.log(' -py, --python Include Python implementations'); console.log(' -go, --go Include Go implementations'); @@ -131,20 +263,17 @@ async function runTest() { console.log(' --log-file= Save verbose output to file'); console.log(' --client= Filter by client name (e.g., httpx, axios)'); console.log(' --server= Filter by server name (e.g., express, fastapi)'); - console.log(' --network= Filter by network (base, base-sepolia)'); - console.log(' --prod= Filter by production vs testnet scenarios'); console.log(' -f, --family= Filter by protocol family (evm, svm) - can be used multiple times'); console.log(' -h, --help Show this help message'); console.log(''); console.log('Examples:'); - console.log(' pnpm test # Run all tests'); - console.log(' pnpm test -d # Run tests in development mode'); + console.log(' pnpm test # Run all v2 tests'); + console.log(' pnpm test -v # Run with verbose logging'); + console.log(' pnpm test --legacy # Include v1 legacy implementations'); + console.log(' pnpm test --legacy -ts # Test legacy + new TypeScript implementations'); console.log(' pnpm test -py -go # Test Python and Go implementations'); - console.log(' pnpm test -ts --client=axios # Test TypeScript axios client'); - console.log(' pnpm test -d -py # Dev mode, Python implementations only'); - console.log(' pnpm test --network=base --prod=true # Base mainnet only'); + console.log(' pnpm test -ts --client=fetch # Test TypeScript fetch client'); console.log(' pnpm test -f evm # Test EVM protocol family only'); - console.log(' pnpm test -f evm -f svm # Test both EVM and SVM protocol families'); console.log(''); return; } @@ -157,7 +286,6 @@ async function runTest() { const serverSvmAddress = process.env.SERVER_SVM_ADDRESS; const clientEvmPrivateKey = process.env.CLIENT_EVM_PRIVATE_KEY; const clientSvmPrivateKey = process.env.CLIENT_SVM_PRIVATE_KEY; - const serverPort = parseInt(process.env.SERVER_PORT || '4021'); if (!serverEvmAddress || !serverSvmAddress || !clientEvmPrivateKey || !clientSvmPrivateKey) { errorLog('āŒ Missing required environment variables:'); @@ -166,7 +294,7 @@ async function runTest() { } // Discover all servers and clients - const discovery = new TestDiscovery('.'); + const discovery = new TestDiscovery('.', includeLegacy); discovery.printDiscoverySummary(); const scenarios = discovery.generateTestScenarios(); @@ -186,10 +314,8 @@ async function runTest() { languageFilters.length > 0 && { name: 'Languages', value: languageFilters.join(', ') }, clientFilter && { name: 'Client', value: clientFilter }, serverFilter && { name: 'Server', value: serverFilter }, - networkFilter && { name: 'Network', value: networkFilter.join(', ') }, - prodFilter && { name: 'Production', value: prodFilter }, protocolFamilyFilters.length > 0 && { name: 'Protocol Families', value: protocolFamilyFilters.join(', ') } - ].filter((f): f is FilterInfo => f !== null && f !== undefined); + ].filter((f): f is FilterInfo => typeof f === 'object' && f !== null && 'name' in f && 'value' in f); log('šŸ“Š Test Scenarios'); log('==============='); @@ -205,11 +331,12 @@ async function runTest() { // Filter scenarios based on command line arguments const filteredScenarios = scenarios.filter(scenario => { - // Language filter - if languages specified, both client and server must match one of them + // Language filter - if languages specified, client, server, AND facilitator must match one of them if (languageFilters.length > 0) { const matchesLanguage = languageFilters.some(lang => scenario.client.config.language.includes(lang) && - scenario.server.config.language.includes(lang) + scenario.server.config.language.includes(lang) && + (!scenario.facilitator || scenario.facilitator.config.language.includes(lang)) ); if (!matchesLanguage) return false; } @@ -220,20 +347,9 @@ async function runTest() { // Server filter - if set, only run tests for this server if (serverFilter && scenario.server.name !== serverFilter) return false; - // Network filter - if set, only run tests for these networks - if (networkFilter && !(networkFilter.includes(scenario.facilitatorNetworkCombo.network))) return false; - // Protocol family filter - if set, only run tests for these protocol families if (protocolFamilyFilters.length > 0 && !protocolFamilyFilters.includes(scenario.protocolFamily)) return false; - // Production filter - if set, filter by production vs testnet scenarios - if (prodFilter !== undefined) { - const isProd = prodFilter.toLowerCase() === 'true'; - const isTestnetOnly = !scenario.facilitatorNetworkCombo.useCdpFacilitator && (scenario.facilitatorNetworkCombo.network === 'base-sepolia' || scenario.facilitatorNetworkCombo.network === 'solana-devnet'); - if (isProd && isTestnetOnly) return false; - if (!isProd && !isTestnetOnly) return false; - } - return true; }); @@ -245,57 +361,217 @@ async function runTest() { log(`Scenarios to run: ${filteredScenarios.length}`); log(''); - // Run filtered scenarios - let passed = 0; - let failed = 0; - - for (let i = 0; i < filteredScenarios.length; i++) { - const scenario = filteredScenarios[i]; - const testNumber = i + 1; - const combo = scenario.facilitatorNetworkCombo; - const comboLabel = `useCdpFacilitator=${combo.useCdpFacilitator}, networks=[${combo.network}]`; - const testName = `${scenario.client.name} → ${scenario.server.name} → ${scenario.endpoint.path} [${comboLabel}]`; - - const serverConfig: ServerConfig = { - port: serverPort, - useCdpFacilitator: combo.useCdpFacilitator, - evmPayTo: serverEvmAddress, - svmPayTo: serverSvmAddress, - evmNetwork: scenario.protocolFamily === 'evm' ? combo.network : 'base-sepolia', - svmNetwork: scenario.protocolFamily === 'svm' ? combo.network : 'solana-devnet', + // Collect unique facilitators and servers + const uniqueFacilitators = new Map(); + const uniqueServers = new Map(); + + filteredScenarios.forEach(scenario => { + if (scenario.facilitator) { + uniqueFacilitators.set(scenario.facilitator.name, scenario.facilitator); + } + uniqueServers.set(scenario.server.name, scenario.server); + }); + + interface DetailedTestResult { + testNumber: number; + client: string; + server: string; + endpoint: string; + facilitator: string; + protocolFamily: string; + passed: boolean; + error?: string; + transaction?: string; + network?: string; + } + + let testResults: DetailedTestResult[] = []; + let testNumber = 0; + let currentPort = 4022; + + // Assign ports and start all facilitators and servers + const facilitatorManagers = new Map(); + const serverInstances = new Map(); + + // Start all facilitators with unique ports + for (const [facilitatorName, facilitator] of uniqueFacilitators) { + const port = currentPort++; + log(`\nšŸ›ļø Starting facilitator: ${facilitatorName} on port ${port}`); + + const manager = new FacilitatorManager( + facilitator.proxy, + port, + 'eip155:84532', + 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1' + ); + facilitatorManagers.set(facilitatorName, manager); + } + + // Start all servers with unique ports + for (const [serverName, server] of uniqueServers) { + const port = currentPort++; + serverInstances.set(serverName, { proxy: server.proxy, port }); + } + + // Wait for all facilitators to be ready + log('\nā³ Waiting for all facilitators to be ready...'); + const facilitatorUrls = new Map(); + + for (const [facilitatorName, manager] of facilitatorManagers) { + const url = await manager.ready(); + if (!url) { + log(`āŒ Failed to start facilitator ${facilitatorName}`); + process.exit(1); + } + facilitatorUrls.set(facilitatorName, url); + log(` āœ… Facilitator ${facilitatorName} ready at ${url}`); + } + + // Start all servers in parallel + log('\nā³ Starting all servers...'); + const serverStartPromises: Promise[] = []; + + for (const [serverName, serverInfo] of serverInstances) { + const serverTask = async () => { + log(` šŸš€ Starting server: ${serverName} on port ${serverInfo.port}`); + + // Find which facilitator URL this server should use (from first matching scenario) + const serverScenario = filteredScenarios.find(s => s.server.name === serverName); + const facilitatorUrl = serverScenario?.facilitator ? + facilitatorUrls.get(serverScenario.facilitator.name) : undefined; + + const serverConfig: ServerConfig = { + port: serverInfo.port, + evmPayTo: serverEvmAddress, + svmPayTo: serverSvmAddress, + evmNetwork: 'eip155:84532', + svmNetwork: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1', + facilitatorUrl, + }; + + const started = await startServer(serverInfo.proxy, serverConfig); + if (!started) { + log(`āŒ Failed to start server ${serverName}`); + process.exit(1); + } + log(` āœ… Server ${serverName} ready`); }; - const callConfig: ClientConfig = { + serverStartPromises.push(serverTask()); + } + + // Wait for all servers to be ready + await Promise.all(serverStartPromises); + + log('\nāœ… All facilitators and servers are ready! Running client tests sequentially...\n'); + + // Run client tests sequentially to avoid nonce conflicts + for (const scenario of filteredScenarios) { + testNumber++; + const facilitatorLabel = scenario.facilitator ? ` via ${scenario.facilitator.name}` : ''; + const testName = `${scenario.client.name} → ${scenario.server.name} → ${scenario.endpoint.path}${facilitatorLabel}`; + + const serverInfo = serverInstances.get(scenario.server.name)!; + + const clientConfig: ClientConfig = { evmPrivateKey: clientEvmPrivateKey, svmPrivateKey: clientSvmPrivateKey, - serverUrl: scenario.server.proxy.getUrl(), - endpointPath: scenario.endpoint.path + serverUrl: `http://localhost:${serverInfo.port}`, + endpointPath: scenario.endpoint.path, }; try { - log(`🧪 Testing #${testNumber}: ${testName}`); - const result = await runCallProtectedScenario( - scenario.server.proxy, - scenario.client.proxy, - serverConfig, - callConfig - ); + log(`🧪 Test #${testNumber}: ${testName}`); + const result = await runClientTest(scenario.client.proxy, clientConfig); + + const detailedResult: DetailedTestResult = { + testNumber, + client: scenario.client.name, + server: scenario.server.name, + endpoint: scenario.endpoint.path, + facilitator: scenario.facilitator?.name || 'none', + protocolFamily: scenario.protocolFamily, + passed: result.success, + error: result.error, + transaction: result.payment_response?.transaction, + network: result.payment_response?.network, + }; if (result.success) { - verboseLog(` āœ… Test passed`); - passed++; + log(` āœ… Test passed`); + testResults.push(detailedResult); } else { - log(`āŒ #${testNumber} ${testName}: ${result.error}`); + log(` āŒ Test failed: ${result.error}`); + + // Print buffered verbose logs only for failed tests + if (result.verboseLogs && result.verboseLogs.length > 0) { + log(` šŸ” Verbose logs:`); + result.verboseLogs.forEach(logLine => log(logLine)); + } + verboseLog(` šŸ” Error details: ${JSON.stringify(result, null, 2)}`); - failed++; + testResults.push(detailedResult); } } catch (error) { - log(`āŒ #${testNumber} ${testName}: ${error}`); + const errorMsg = error instanceof Error ? error.message : String(error); + log(` āŒ Test failed with exception: ${errorMsg}`); verboseLog(` šŸ” Exception details: ${error}`); - failed++; + testResults.push({ + testNumber, + client: scenario.client.name, + server: scenario.server.name, + endpoint: scenario.endpoint.path, + facilitator: scenario.facilitator?.name || 'none', + protocolFamily: scenario.protocolFamily, + passed: false, + error: errorMsg, + }); } + + // Delay between tests to prevent timing/state/nonce issues + await new Promise(resolve => setTimeout(resolve, 5000)); } + // Run discovery validation before cleanup (while facilitators are still running) + const facilitatorsWithConfig = Array.from(uniqueFacilitators.values()).map((f: any) => ({ + proxy: facilitatorManagers.get(f.name)!.getProxy(), + config: f.config, + })); + + const serversArray = Array.from(uniqueServers.values()); + const serverPortsMap = new Map( + Array.from(serverInstances.entries()).map(([name, info]) => [name, info.port]) + ); + + if (shouldRunDiscoveryValidation(facilitatorsWithConfig, serversArray)) { + await handleDiscoveryValidation( + facilitatorsWithConfig, + serversArray, + serverPortsMap + ); + } + + // Clean up servers and facilitators in parallel + log('\n🧹 Cleaning up...'); + + const serverStopPromises: Promise[] = []; + for (const [serverName, serverInfo] of serverInstances) { + log(` šŸ›‘ Stopping server: ${serverName}`); + serverStopPromises.push(serverInfo.proxy.stop()); + } + await Promise.all(serverStopPromises); + + const facilitatorStopPromises: Promise[] = []; + for (const [facilitatorName, manager] of facilitatorManagers) { + log(` šŸ›‘ Stopping facilitator: ${facilitatorName}`); + facilitatorStopPromises.push(manager.stop()); + } + await Promise.all(facilitatorStopPromises); + + // Calculate totals + const passed = testResults.filter(r => r.passed).length; + const failed = testResults.filter(r => !r.passed).length; + // Summary log(''); log('šŸ“Š Test Summary'); @@ -303,21 +579,106 @@ async function runTest() { log(`āœ… Passed: ${passed}`); log(`āŒ Failed: ${failed}`); log(`šŸ“ˆ Total: ${passed + failed}`); + log(''); + + // Detailed results table + log('šŸ“‹ Detailed Test Results'); + log('========================'); + log(''); + + // Group by status + const passedTests = testResults.filter(r => r.passed); + const failedTests = testResults.filter(r => !r.passed); + + if (passedTests.length > 0) { + log('āœ… PASSED TESTS:'); + log(''); + passedTests.forEach(test => { + const txInfo = test.transaction ? ` | Tx: ${test.transaction.substring(0, 10)}...` : ''; + log(` #${test.testNumber.toString().padStart(2, ' ')}: ${test.client} → ${test.server} → ${test.endpoint}`); + log(` Facilitator: ${test.facilitator} | Network: ${test.network || 'N/A'}${txInfo}`); + }); + log(''); + } + + if (failedTests.length > 0) { + log('āŒ FAILED TESTS:'); + log(''); + failedTests.forEach(test => { + log(` #${test.testNumber.toString().padStart(2, ' ')}: ${test.client} → ${test.server} → ${test.endpoint}`); + log(` Facilitator: ${test.facilitator}`); + log(` Error: ${test.error || 'Unknown error'}`); + }); + log(''); + } + + // Breakdown by facilitator + const facilitatorBreakdown = testResults.reduce((acc, test) => { + const key = test.facilitator; + if (!acc[key]) acc[key] = { passed: 0, failed: 0 }; + if (test.passed) acc[key].passed++; + else acc[key].failed++; + return acc; + }, {} as Record); + + log('šŸ“Š Breakdown by Facilitator:'); + Object.entries(facilitatorBreakdown).forEach(([facilitator, stats]) => { + const total = stats.passed + stats.failed; + const passRate = total > 0 ? Math.round((stats.passed / total) * 100) : 0; + log(` ${facilitator.padEnd(15)} āœ… ${stats.passed} / āŒ ${stats.failed} (${passRate}%)`); + }); + log(''); + + // Breakdown by server + const serverBreakdown = testResults.reduce((acc, test) => { + const key = test.server; + if (!acc[key]) acc[key] = { passed: 0, failed: 0 }; + if (test.passed) acc[key].passed++; + else acc[key].failed++; + return acc; + }, {} as Record); + + log('šŸ“Š Breakdown by Server:'); + Object.entries(serverBreakdown).forEach(([server, stats]) => { + const total = stats.passed + stats.failed; + const passRate = total > 0 ? Math.round((stats.passed / total) * 100) : 0; + log(` ${server.padEnd(20)} āœ… ${stats.passed} / āŒ ${stats.failed} (${passRate}%)`); + }); + log(''); + + // Breakdown by client + const clientBreakdown = testResults.reduce((acc, test) => { + const key = test.client; + if (!acc[key]) acc[key] = { passed: 0, failed: 0 }; + if (test.passed) acc[key].passed++; + else acc[key].failed++; + return acc; + }, {} as Record); + + log('šŸ“Š Breakdown by Client:'); + Object.entries(clientBreakdown).forEach(([client, stats]) => { + const total = stats.passed + stats.failed; + const passRate = total > 0 ? Math.round((stats.passed / total) * 100) : 0; + log(` ${client.padEnd(20)} āœ… ${stats.passed} / āŒ ${stats.failed} (${passRate}%)`); + }); + log(''); // Protocol family breakdown - const protocolBreakdown = filteredScenarios.reduce((acc, scenario) => { - const key = scenario.protocolFamily; - if (!acc[key]) acc[key] = { passed: 0, failed: 0, total: 0 }; - acc[key].total++; + const protocolBreakdown = testResults.reduce((acc, test) => { + const key = test.protocolFamily; + if (!acc[key]) acc[key] = { passed: 0, failed: 0 }; + if (test.passed) acc[key].passed++; + else acc[key].failed++; return acc; - }, {} as Record); + }, {} as Record); if (Object.keys(protocolBreakdown).length > 1) { - log(''); log('šŸ“Š Protocol Family Breakdown:'); Object.entries(protocolBreakdown).forEach(([protocol, stats]) => { - log(` ${protocol.toUpperCase()}: ${stats.total} scenarios tested`); + const total = stats.passed + stats.failed; + log(` ${protocol.toUpperCase()}: āœ… ${stats.passed} / āŒ ${stats.failed} / šŸ“ˆ ${total} total`); }); + log(''); } // Close logger diff --git a/e2e/tsconfig.json b/e2e/tsconfig.json index 3df0e399f..2f152d983 100644 --- a/e2e/tsconfig.json +++ b/e2e/tsconfig.json @@ -1,12 +1,12 @@ { "compilerOptions": { "target": "ES2020", - "module": "commonjs", + "module": "ES2020", + "moduleResolution": "bundler", "lib": [ "ES2020" ], "outDir": "./dist", - "rootDir": ".", "strict": true, "esModuleInterop": true, "skipLibCheck": true, diff --git a/examples/python/clients/httpx/.env-local b/examples/python/legacy/clients/httpx/.env-local similarity index 100% rename from examples/python/clients/httpx/.env-local rename to examples/python/legacy/clients/httpx/.env-local diff --git a/examples/python/clients/httpx/README.md b/examples/python/legacy/clients/httpx/README.md similarity index 100% rename from examples/python/clients/httpx/README.md rename to examples/python/legacy/clients/httpx/README.md diff --git a/examples/python/clients/httpx/extensible.py b/examples/python/legacy/clients/httpx/extensible.py similarity index 100% rename from examples/python/clients/httpx/extensible.py rename to examples/python/legacy/clients/httpx/extensible.py diff --git a/examples/python/clients/httpx/main.py b/examples/python/legacy/clients/httpx/main.py similarity index 100% rename from examples/python/clients/httpx/main.py rename to examples/python/legacy/clients/httpx/main.py diff --git a/examples/python/clients/httpx/pyproject.toml b/examples/python/legacy/clients/httpx/pyproject.toml similarity index 100% rename from examples/python/clients/httpx/pyproject.toml rename to examples/python/legacy/clients/httpx/pyproject.toml diff --git a/examples/python/clients/httpx/uv.lock b/examples/python/legacy/clients/httpx/uv.lock similarity index 100% rename from examples/python/clients/httpx/uv.lock rename to examples/python/legacy/clients/httpx/uv.lock diff --git a/examples/python/clients/requests/.env-local b/examples/python/legacy/clients/requests/.env-local similarity index 100% rename from examples/python/clients/requests/.env-local rename to examples/python/legacy/clients/requests/.env-local diff --git a/examples/python/clients/requests/README.md b/examples/python/legacy/clients/requests/README.md similarity index 100% rename from examples/python/clients/requests/README.md rename to examples/python/legacy/clients/requests/README.md diff --git a/examples/python/clients/requests/extensible.py b/examples/python/legacy/clients/requests/extensible.py similarity index 100% rename from examples/python/clients/requests/extensible.py rename to examples/python/legacy/clients/requests/extensible.py diff --git a/examples/python/clients/requests/main.py b/examples/python/legacy/clients/requests/main.py similarity index 100% rename from examples/python/clients/requests/main.py rename to examples/python/legacy/clients/requests/main.py diff --git a/examples/python/clients/requests/pyproject.toml b/examples/python/legacy/clients/requests/pyproject.toml similarity index 100% rename from examples/python/clients/requests/pyproject.toml rename to examples/python/legacy/clients/requests/pyproject.toml diff --git a/examples/python/clients/requests/uv.lock b/examples/python/legacy/clients/requests/uv.lock similarity index 100% rename from examples/python/clients/requests/uv.lock rename to examples/python/legacy/clients/requests/uv.lock diff --git a/examples/python/discovery/README.md b/examples/python/legacy/discovery/README.md similarity index 100% rename from examples/python/discovery/README.md rename to examples/python/legacy/discovery/README.md diff --git a/examples/python/discovery/main.py b/examples/python/legacy/discovery/main.py similarity index 100% rename from examples/python/discovery/main.py rename to examples/python/legacy/discovery/main.py diff --git a/examples/python/discovery/pyproject.toml b/examples/python/legacy/discovery/pyproject.toml similarity index 100% rename from examples/python/discovery/pyproject.toml rename to examples/python/legacy/discovery/pyproject.toml diff --git a/examples/python/discovery/uv.lock b/examples/python/legacy/discovery/uv.lock similarity index 100% rename from examples/python/discovery/uv.lock rename to examples/python/legacy/discovery/uv.lock diff --git a/examples/python/fullstack/fastapi/.env-local b/examples/python/legacy/fullstack/fastapi/.env-local similarity index 100% rename from examples/python/fullstack/fastapi/.env-local rename to examples/python/legacy/fullstack/fastapi/.env-local diff --git a/examples/python/fullstack/fastapi/README.md b/examples/python/legacy/fullstack/fastapi/README.md similarity index 100% rename from examples/python/fullstack/fastapi/README.md rename to examples/python/legacy/fullstack/fastapi/README.md diff --git a/examples/python/fullstack/fastapi/main.py b/examples/python/legacy/fullstack/fastapi/main.py similarity index 100% rename from examples/python/fullstack/fastapi/main.py rename to examples/python/legacy/fullstack/fastapi/main.py diff --git a/examples/python/fullstack/fastapi/pyproject.toml b/examples/python/legacy/fullstack/fastapi/pyproject.toml similarity index 100% rename from examples/python/fullstack/fastapi/pyproject.toml rename to examples/python/legacy/fullstack/fastapi/pyproject.toml diff --git a/examples/python/fullstack/fastapi/static/premium.html b/examples/python/legacy/fullstack/fastapi/static/premium.html similarity index 100% rename from examples/python/fullstack/fastapi/static/premium.html rename to examples/python/legacy/fullstack/fastapi/static/premium.html diff --git a/examples/python/fullstack/fastapi/static/x402.png b/examples/python/legacy/fullstack/fastapi/static/x402.png similarity index 100% rename from examples/python/fullstack/fastapi/static/x402.png rename to examples/python/legacy/fullstack/fastapi/static/x402.png diff --git a/examples/python/fullstack/fastapi/uv.lock b/examples/python/legacy/fullstack/fastapi/uv.lock similarity index 100% rename from examples/python/fullstack/fastapi/uv.lock rename to examples/python/legacy/fullstack/fastapi/uv.lock diff --git a/examples/python/fullstack/flask/.env-local b/examples/python/legacy/fullstack/flask/.env-local similarity index 100% rename from examples/python/fullstack/flask/.env-local rename to examples/python/legacy/fullstack/flask/.env-local diff --git a/examples/python/fullstack/flask/README.md b/examples/python/legacy/fullstack/flask/README.md similarity index 100% rename from examples/python/fullstack/flask/README.md rename to examples/python/legacy/fullstack/flask/README.md diff --git a/examples/python/fullstack/flask/main.py b/examples/python/legacy/fullstack/flask/main.py similarity index 100% rename from examples/python/fullstack/flask/main.py rename to examples/python/legacy/fullstack/flask/main.py diff --git a/examples/python/fullstack/flask/pyproject.toml b/examples/python/legacy/fullstack/flask/pyproject.toml similarity index 100% rename from examples/python/fullstack/flask/pyproject.toml rename to examples/python/legacy/fullstack/flask/pyproject.toml diff --git a/examples/python/fullstack/flask/static/premium.html b/examples/python/legacy/fullstack/flask/static/premium.html similarity index 100% rename from examples/python/fullstack/flask/static/premium.html rename to examples/python/legacy/fullstack/flask/static/premium.html diff --git a/examples/python/fullstack/flask/static/x402.png b/examples/python/legacy/fullstack/flask/static/x402.png similarity index 100% rename from examples/python/fullstack/flask/static/x402.png rename to examples/python/legacy/fullstack/flask/static/x402.png diff --git a/examples/python/fullstack/flask/uv.lock b/examples/python/legacy/fullstack/flask/uv.lock similarity index 100% rename from examples/python/fullstack/flask/uv.lock rename to examples/python/legacy/fullstack/flask/uv.lock diff --git a/examples/python/servers/advanced/.env-local b/examples/python/legacy/servers/advanced/.env-local similarity index 100% rename from examples/python/servers/advanced/.env-local rename to examples/python/legacy/servers/advanced/.env-local diff --git a/examples/python/servers/advanced/README.md b/examples/python/legacy/servers/advanced/README.md similarity index 100% rename from examples/python/servers/advanced/README.md rename to examples/python/legacy/servers/advanced/README.md diff --git a/examples/python/servers/advanced/main.py b/examples/python/legacy/servers/advanced/main.py similarity index 100% rename from examples/python/servers/advanced/main.py rename to examples/python/legacy/servers/advanced/main.py diff --git a/examples/python/servers/advanced/pyproject.toml b/examples/python/legacy/servers/advanced/pyproject.toml similarity index 100% rename from examples/python/servers/advanced/pyproject.toml rename to examples/python/legacy/servers/advanced/pyproject.toml diff --git a/examples/python/servers/advanced/uv.lock b/examples/python/legacy/servers/advanced/uv.lock similarity index 100% rename from examples/python/servers/advanced/uv.lock rename to examples/python/legacy/servers/advanced/uv.lock diff --git a/examples/python/servers/fastapi/.env-local b/examples/python/legacy/servers/fastapi/.env-local similarity index 100% rename from examples/python/servers/fastapi/.env-local rename to examples/python/legacy/servers/fastapi/.env-local diff --git a/examples/python/servers/fastapi/README.md b/examples/python/legacy/servers/fastapi/README.md similarity index 100% rename from examples/python/servers/fastapi/README.md rename to examples/python/legacy/servers/fastapi/README.md diff --git a/examples/python/servers/fastapi/main.py b/examples/python/legacy/servers/fastapi/main.py similarity index 100% rename from examples/python/servers/fastapi/main.py rename to examples/python/legacy/servers/fastapi/main.py diff --git a/examples/python/servers/fastapi/pyproject.toml b/examples/python/legacy/servers/fastapi/pyproject.toml similarity index 100% rename from examples/python/servers/fastapi/pyproject.toml rename to examples/python/legacy/servers/fastapi/pyproject.toml diff --git a/examples/python/servers/fastapi/uv.lock b/examples/python/legacy/servers/fastapi/uv.lock similarity index 100% rename from examples/python/servers/fastapi/uv.lock rename to examples/python/legacy/servers/fastapi/uv.lock diff --git a/examples/python/servers/flask/.env-local b/examples/python/legacy/servers/flask/.env-local similarity index 100% rename from examples/python/servers/flask/.env-local rename to examples/python/legacy/servers/flask/.env-local diff --git a/examples/python/servers/flask/README.md b/examples/python/legacy/servers/flask/README.md similarity index 100% rename from examples/python/servers/flask/README.md rename to examples/python/legacy/servers/flask/README.md diff --git a/examples/python/servers/flask/main.py b/examples/python/legacy/servers/flask/main.py similarity index 100% rename from examples/python/servers/flask/main.py rename to examples/python/legacy/servers/flask/main.py diff --git a/examples/python/servers/flask/pyproject.toml b/examples/python/legacy/servers/flask/pyproject.toml similarity index 100% rename from examples/python/servers/flask/pyproject.toml rename to examples/python/legacy/servers/flask/pyproject.toml diff --git a/examples/python/servers/flask/uv.lock b/examples/python/legacy/servers/flask/uv.lock similarity index 100% rename from examples/python/servers/flask/uv.lock rename to examples/python/legacy/servers/flask/uv.lock diff --git a/examples/python/servers/mainnet/.env-local b/examples/python/legacy/servers/mainnet/.env-local similarity index 100% rename from examples/python/servers/mainnet/.env-local rename to examples/python/legacy/servers/mainnet/.env-local diff --git a/examples/python/servers/mainnet/README.md b/examples/python/legacy/servers/mainnet/README.md similarity index 100% rename from examples/python/servers/mainnet/README.md rename to examples/python/legacy/servers/mainnet/README.md diff --git a/examples/python/servers/mainnet/main.py b/examples/python/legacy/servers/mainnet/main.py similarity index 100% rename from examples/python/servers/mainnet/main.py rename to examples/python/legacy/servers/mainnet/main.py diff --git a/examples/python/servers/mainnet/pyproject.toml b/examples/python/legacy/servers/mainnet/pyproject.toml similarity index 100% rename from examples/python/servers/mainnet/pyproject.toml rename to examples/python/legacy/servers/mainnet/pyproject.toml diff --git a/examples/python/servers/mainnet/uv.lock b/examples/python/legacy/servers/mainnet/uv.lock similarity index 100% rename from examples/python/servers/mainnet/uv.lock rename to examples/python/legacy/servers/mainnet/uv.lock diff --git a/examples/python/sync.py b/examples/python/legacy/sync.py similarity index 100% rename from examples/python/sync.py rename to examples/python/legacy/sync.py diff --git a/examples/typescript/clients/chainlink-vrf-nft/package-lock.json b/examples/typescript/clients/chainlink-vrf-nft/package-lock.json deleted file mode 100644 index 3a04a0557..000000000 --- a/examples/typescript/clients/chainlink-vrf-nft/package-lock.json +++ /dev/null @@ -1,1165 +0,0 @@ -{ - "name": "vrfnft-example", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "vrfnft-example", - "version": "0.1.0", - "dependencies": { - "@hono/node-server": "^1.13.8", - "dotenv": "^16.4.5", - "hono": "^4.7.2", - "viem": "^2.23.5", - "x402": "file:../../../../typescript/packages/x402" - }, - "devDependencies": { - "@types/node": "^22.13.5", - "tsx": "^4.19.3" - } - }, - "../../../../typescript/packages/x402": { - "version": "0.2.0", - "license": "Apache-2.0", - "dependencies": { - "@coinbase/cdp-sdk": "^1.1.1", - "axios": "^1.7.9", - "viem": "^2.21.26", - "zod": "^3.24.2" - }, - "devDependencies": { - "@eslint/js": "^9.24.0", - "@types/node": "^22.13.4", - "@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.19.2", - "typescript": "^5.7.3", - "vite": "^6.2.6", - "vite-tsconfig-paths": "^5.1.4", - "vitest": "^3.0.5" - } - }, - "../../../../typescript/packages/x402/node_modules/@coinbase/cdp-sdk": { - "resolved": "../../node_modules/.pnpm/@coinbase+cdp-sdk@1.1.2_bufferutil@4.0.9_typescript@5.8.3_utf-8-validate@5.0.10_zod@3.24.3/node_modules/@coinbase/cdp-sdk", - "link": true - }, - "../../../../typescript/packages/x402/node_modules/@eslint/js": { - "resolved": "../../node_modules/.pnpm/@eslint+js@9.24.0/node_modules/@eslint/js", - "link": true - }, - "../../../../typescript/packages/x402/node_modules/@types/node": { - "resolved": "../../node_modules/.pnpm/@types+node@22.14.1/node_modules/@types/node", - "link": true - }, - "../../../../typescript/packages/x402/node_modules/@typescript-eslint/eslint-plugin": { - "resolved": "../../node_modules/.pnpm/@typescript-eslint+eslint-plugin@8.30.1_@typescript-eslint+parser@8.30.1_eslint@9.24.0__beb2a5db574f326f24c476c3022a6373/node_modules/@typescript-eslint/eslint-plugin", - "link": true - }, - "../../../../typescript/packages/x402/node_modules/@typescript-eslint/parser": { - "resolved": "../../node_modules/.pnpm/@typescript-eslint+parser@8.30.1_eslint@9.24.0_jiti@1.21.7__typescript@5.8.3/node_modules/@typescript-eslint/parser", - "link": true - }, - "../../../../typescript/packages/x402/node_modules/axios": { - "resolved": "../../node_modules/.pnpm/axios@1.8.4/node_modules/axios", - "link": true - }, - "../../../../typescript/packages/x402/node_modules/eslint": { - "resolved": "../../node_modules/.pnpm/eslint@9.24.0_jiti@1.21.7/node_modules/eslint", - "link": true - }, - "../../../../typescript/packages/x402/node_modules/eslint-plugin-import": { - "resolved": "../../node_modules/.pnpm/eslint-plugin-import@2.31.0_@typescript-eslint+parser@8.30.1_eslint@9.24.0_jiti@1.21.7__047cccc7d02cbbe44b50dd3c9d1bc175/node_modules/eslint-plugin-import", - "link": true - }, - "../../../../typescript/packages/x402/node_modules/eslint-plugin-jsdoc": { - "resolved": "../../node_modules/.pnpm/eslint-plugin-jsdoc@50.6.9_eslint@9.24.0_jiti@1.21.7_/node_modules/eslint-plugin-jsdoc", - "link": true - }, - "../../../../typescript/packages/x402/node_modules/eslint-plugin-prettier": { - "resolved": "../../node_modules/.pnpm/eslint-plugin-prettier@5.2.6_eslint@9.24.0_jiti@1.21.7__prettier@3.5.2/node_modules/eslint-plugin-prettier", - "link": true - }, - "../../../../typescript/packages/x402/node_modules/prettier": { - "resolved": "../../node_modules/.pnpm/prettier@3.5.2/node_modules/prettier", - "link": true - }, - "../../../../typescript/packages/x402/node_modules/tsx": { - "resolved": "../../node_modules/.pnpm/tsx@4.19.3/node_modules/tsx", - "link": true - }, - "../../../../typescript/packages/x402/node_modules/typescript": { - "resolved": "../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript", - "link": true - }, - "../../../../typescript/packages/x402/node_modules/viem": { - "resolved": "../../node_modules/.pnpm/viem@2.27.2_bufferutil@4.0.9_typescript@5.8.3_utf-8-validate@5.0.10_zod@3.24.3/node_modules/viem", - "link": true - }, - "../../../../typescript/packages/x402/node_modules/vite": { - "resolved": "../../node_modules/.pnpm/vite@6.3.2_@types+node@22.14.1_jiti@1.21.7_tsx@4.19.3_yaml@2.7.1/node_modules/vite", - "link": true - }, - "../../../../typescript/packages/x402/node_modules/vite-tsconfig-paths": { - "resolved": "../../node_modules/.pnpm/vite-tsconfig-paths@5.1.4_typescript@5.8.3_vite@6.3.2_@types+node@22.14.1_jiti@1.21.7_tsx@4.19.3_yaml@2.7.1_/node_modules/vite-tsconfig-paths", - "link": true - }, - "../../../../typescript/packages/x402/node_modules/vitest": { - "resolved": "../../node_modules/.pnpm/vitest@3.1.1_@types+node@22.14.1_jiti@1.21.7_tsx@4.19.3_yaml@2.7.1/node_modules/vitest", - "link": true - }, - "../../../../typescript/packages/x402/node_modules/zod": { - "resolved": "../../node_modules/.pnpm/zod@3.24.3/node_modules/zod", - "link": true - }, - "../../node_modules/.pnpm/@coinbase+cdp-sdk@1.1.2_bufferutil@4.0.9_typescript@5.8.3_utf-8-validate@5.0.10_zod@3.24.3/node_modules/@coinbase/cdp-sdk": { - "version": "1.1.2", - "license": "MIT", - "dependencies": { - "@solana/web3.js": "^1.98.0", - "abitype": "1.0.6", - "axios": "^1.8.2", - "jose": "^6.0.8", - "md5": "^2.3.0", - "viem": "^2.21.26" - }, - "devDependencies": { - "@changesets/changelog-github": "^0.5.1", - "@changesets/cli": "^2.28.1", - "@faker-js/faker": "^9.6.0", - "@types/node": "^20.12.11", - "@typescript-eslint/eslint-plugin": "^7.18.0", - "@typescript-eslint/parser": "^7.18.0", - "@vitest/coverage-v8": "^1.4.0", - "bs58": "^6.0.0", - "dotenv": "^16.4.7", - "eslint": "^8.57.1", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-jsdoc": "^48.11.0", - "eslint-plugin-prettier": "^5.2.5", - "msw": "^2.7.3", - "orval": "^7.6.0", - "prettier": "^3.2.5", - "tsx": "^4.19.3", - "typedoc": "^0.27.2", - "typescript": "^5.4.5", - "uuid": "^11.1.0", - "vitest": "^1.4.0" - } - }, - "../../node_modules/.pnpm/@eslint+js@9.24.0/node_modules/@eslint/js": { - "version": "9.24.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "../../node_modules/.pnpm/@hono+node-server@1.14.1_hono@4.7.7/node_modules/@hono/node-server": { - "version": "1.14.1", - "license": "MIT", - "devDependencies": { - "@hono/eslint-config": "^1.0.1", - "@types/jest": "^29.5.3", - "@types/node": "^20.10.0", - "@types/supertest": "^2.0.12", - "@whatwg-node/fetch": "^0.9.14", - "eslint": "^9.10.0", - "hono": "^4.4.10", - "jest": "^29.6.1", - "np": "^7.7.0", - "prettier": "^3.2.4", - "publint": "^0.1.16", - "supertest": "^6.3.3", - "ts-jest": "^29.1.1", - "tsup": "^7.2.0", - "typescript": "^5.3.2" - }, - "engines": { - "node": ">=18.14.1" - }, - "peerDependencies": { - "hono": "^4" - } - }, - "../../node_modules/.pnpm/@types+node@22.14.1/node_modules/@types/node": { - "version": "22.14.1", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "../../node_modules/.pnpm/@typescript-eslint+eslint-plugin@8.30.1_@typescript-eslint+parser@8.30.1_eslint@9.24.0__beb2a5db574f326f24c476c3022a6373/node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.30.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.30.1", - "@typescript-eslint/type-utils": "8.30.1", - "@typescript-eslint/utils": "8.30.1", - "@typescript-eslint/visitor-keys": "8.30.1", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.0.1" - }, - "devDependencies": { - "@jest/types": "29.6.3", - "@types/marked": "^5.0.2", - "@types/mdast": "^4.0.3", - "@types/natural-compare": "*", - "@typescript-eslint/rule-schema-to-typescript-types": "8.30.1", - "@typescript-eslint/rule-tester": "8.30.1", - "ajv": "^6.12.6", - "cross-env": "^7.0.3", - "cross-fetch": "*", - "eslint": "*", - "jest": "29.7.0", - "jest-specific-snapshot": "^8.0.0", - "json-schema": "*", - "markdown-table": "^3.0.3", - "marked": "^5.1.2", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-mdx": "^3.0.0", - "micromark-extension-mdxjs": "^3.0.0", - "prettier": "^3.2.5", - "rimraf": "*", - "title-case": "^3.0.3", - "tsx": "*", - "typescript": "*", - "unist-util-visit": "^5.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "../../node_modules/.pnpm/@typescript-eslint+parser@8.30.1_eslint@9.24.0_jiti@1.21.7__typescript@5.8.3/node_modules/@typescript-eslint/parser": { - "version": "8.30.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/scope-manager": "8.30.1", - "@typescript-eslint/types": "8.30.1", - "@typescript-eslint/typescript-estree": "8.30.1", - "@typescript-eslint/visitor-keys": "8.30.1", - "debug": "^4.3.4" - }, - "devDependencies": { - "@vitest/coverage-v8": "^3.1.1", - "glob": "*", - "prettier": "^3.2.5", - "rimraf": "*", - "typescript": "*", - "vitest": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "../../node_modules/.pnpm/axios@1.8.4/node_modules/axios": { - "version": "1.8.4", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - }, - "devDependencies": { - "@babel/core": "^7.23.9", - "@babel/preset-env": "^7.23.9", - "@commitlint/cli": "^17.8.1", - "@commitlint/config-conventional": "^17.8.1", - "@release-it/conventional-changelog": "^5.1.1", - "@rollup/plugin-alias": "^5.1.0", - "@rollup/plugin-babel": "^5.3.1", - "@rollup/plugin-commonjs": "^15.1.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-multi-entry": "^4.1.0", - "@rollup/plugin-node-resolve": "^9.0.0", - "abortcontroller-polyfill": "^1.7.5", - "auto-changelog": "^2.4.0", - "body-parser": "^1.20.2", - "chalk": "^5.3.0", - "coveralls": "^3.1.1", - "cross-env": "^7.0.3", - "dev-null": "^0.1.1", - "dtslint": "^4.2.1", - "es6-promise": "^4.2.8", - "eslint": "^8.56.0", - "express": "^4.18.2", - "formdata-node": "^5.0.1", - "formidable": "^2.1.2", - "fs-extra": "^10.1.0", - "get-stream": "^3.0.0", - "gulp": "^4.0.2", - "gzip-size": "^7.0.0", - "handlebars": "^4.7.8", - "husky": "^8.0.3", - "istanbul-instrumenter-loader": "^3.0.1", - "jasmine-core": "^2.99.1", - "karma": "^6.3.17", - "karma-chrome-launcher": "^3.2.0", - "karma-firefox-launcher": "^2.1.2", - "karma-jasmine": "^1.1.2", - "karma-jasmine-ajax": "^0.1.13", - "karma-rollup-preprocessor": "^7.0.8", - "karma-safari-launcher": "^1.0.0", - "karma-sauce-launcher": "^4.3.6", - "karma-sinon": "^1.0.5", - "karma-sourcemap-loader": "^0.3.8", - "memoizee": "^0.4.15", - "minimist": "^1.2.8", - "mocha": "^10.3.0", - "multer": "^1.4.4", - "pretty-bytes": "^6.1.1", - "release-it": "^15.11.0", - "rollup": "^2.79.1", - "rollup-plugin-auto-external": "^2.0.0", - "rollup-plugin-bundle-size": "^1.0.3", - "rollup-plugin-terser": "^7.0.2", - "sinon": "^4.5.0", - "stream-throttle": "^0.1.3", - "string-replace-async": "^3.0.2", - "terser-webpack-plugin": "^4.2.3", - "typescript": "^4.9.5" - } - }, - "../../node_modules/.pnpm/dotenv@16.5.0/node_modules/dotenv": { - "version": "16.5.0", - "license": "BSD-2-Clause", - "devDependencies": { - "@types/node": "^18.11.3", - "decache": "^4.6.2", - "sinon": "^14.0.1", - "standard": "^17.0.0", - "standard-version": "^9.5.0", - "tap": "^19.2.0", - "typescript": "^4.8.4" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "../../node_modules/.pnpm/eslint-plugin-import@2.31.0_@typescript-eslint+parser@8.30.1_eslint@9.24.0_jiti@1.21.7__047cccc7d02cbbe44b50dd3c9d1bc175/node_modules/eslint-plugin-import": { - "version": "2.31.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@rtsao/scc": "^1.1.0", - "array-includes": "^3.1.8", - "array.prototype.findlastindex": "^1.2.5", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.12.0", - "hasown": "^2.0.2", - "is-core-module": "^2.15.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.8", - "object.groupby": "^1.0.3", - "object.values": "^1.2.0", - "semver": "^6.3.1", - "string.prototype.trimend": "^1.0.8", - "tsconfig-paths": "^3.15.0" - }, - "devDependencies": { - "@angular-eslint/template-parser": "^13.5.0", - "@eslint/import-test-order-redirect-scoped": "file:./tests/files/order-redirect-scoped", - "@test-scope/some-module": "file:./tests/files/symlinked-module", - "@typescript-eslint/parser": "^2.23.0 || ^3.3.0 || ^4.29.3 || ^5.10.0", - "babel-cli": "^6.26.0", - "babel-core": "^6.26.3", - "babel-eslint": "=8.0.3 || ^8.2.6", - "babel-plugin-istanbul": "^4.1.6", - "babel-plugin-module-resolver": "^2.7.1", - "babel-preset-airbnb": "^2.6.0", - "babel-preset-flow": "^6.23.0", - "babel-register": "^6.26.0", - "babylon": "^6.18.0", - "chai": "^4.3.10", - "cross-env": "^4.0.0", - "escope": "^3.6.0", - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9", - "eslint-doc-generator": "^1.6.1", - "eslint-import-resolver-node": "file:./resolvers/node", - "eslint-import-resolver-typescript": "^1.0.2 || ^1.1.1", - "eslint-import-resolver-webpack": "file:./resolvers/webpack", - "eslint-import-test-order-redirect": "file:./tests/files/order-redirect", - "eslint-module-utils": "file:./utils", - "eslint-plugin-eslint-plugin": "^2.3.0", - "eslint-plugin-import": "2.x", - "eslint-plugin-json": "^2.1.2", - "find-babel-config": "=1.2.0", - "fs-copy-file-sync": "^1.1.1", - "glob": "^7.2.3", - "in-publish": "^2.0.1", - "jackspeak": "=2.1.1", - "jsonc-parser": "=3.2.0", - "linklocal": "^2.8.2", - "lodash.isarray": "^4.0.0", - "markdownlint-cli": "~0.35", - "mocha": "^3.5.3", - "npm-which": "^3.0.1", - "nyc": "^11.9.0", - "redux": "^3.7.2", - "rimraf": "^2.7.1", - "safe-publish-latest": "^2.0.0", - "sinon": "^2.4.1", - "typescript": "^2.8.1 || ~3.9.5 || ~4.5.2", - "typescript-eslint-parser": "^15 || ^20 || ^22" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" - } - }, - "../../node_modules/.pnpm/eslint-plugin-jsdoc@50.6.9_eslint@9.24.0_jiti@1.21.7_/node_modules/eslint-plugin-jsdoc": { - "version": "50.6.9", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@es-joy/jsdoccomment": "~0.49.0", - "are-docs-informative": "^0.0.2", - "comment-parser": "1.4.1", - "debug": "^4.3.6", - "escape-string-regexp": "^4.0.0", - "espree": "^10.1.0", - "esquery": "^1.6.0", - "parse-imports": "^2.1.1", - "semver": "^7.6.3", - "spdx-expression-parse": "^4.0.0", - "synckit": "^0.9.1" - }, - "devDependencies": { - "@babel/cli": "^7.24.8", - "@babel/core": "^7.25.2", - "@babel/eslint-parser": "^7.25.1", - "@babel/node": "^7.25.0", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-transform-flow-strip-types": "^7.25.2", - "@babel/preset-env": "^7.25.3", - "@es-joy/escodegen": "^3.5.1", - "@es-joy/jsdoc-eslint-parser": "^0.21.1", - "@hkdobrev/run-if-changed": "^0.6.0", - "@semantic-release/commit-analyzer": "^13.0.0", - "@semantic-release/github": "^11.0.0", - "@semantic-release/npm": "^12.0.1", - "@types/chai": "^4.3.17", - "@types/debug": "^4.1.12", - "@types/eslint": "^9.6.0", - "@types/espree": "^10.1.0", - "@types/esquery": "^1.5.4", - "@types/estree": "^1.0.5", - "@types/json-schema": "^7.0.15", - "@types/lodash.defaultsdeep": "^4.6.9", - "@types/mocha": "^10.0.7", - "@types/node": "^22.2.0", - "@types/semver": "^7.5.8", - "@types/spdx-expression-parse": "^3.0.5", - "@typescript-eslint/types": "^8.1.0", - "babel-plugin-add-module-exports": "^1.0.4", - "babel-plugin-istanbul": "^7.0.0", - "babel-plugin-transform-import-meta": "^2.2.1", - "c8": "^10.1.2", - "camelcase": "^8.0.0", - "chai": "^5.1.1", - "cross-env": "^7.0.3", - "decamelize": "^6.0.0", - "eslint": "9.9.0", - "eslint-config-canonical": "~43.0.15", - "gitdown": "^4.1.1", - "glob": "^10.4.2", - "globals": "^15.9.0", - "husky": "^9.1.4", - "jsdoc-type-pratt-parser": "^4.1.0", - "json-schema": "^0.4.0", - "lint-staged": "^15.2.9", - "lodash.defaultsdeep": "^4.6.1", - "mocha": "^10.7.3", - "open-editor": "^5.0.0", - "replace": "^1.2.2", - "rimraf": "^5.0.7", - "semantic-release": "^24.1.1", - "typescript": "5.5.x", - "typescript-eslint": "^8.1.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" - } - }, - "../../node_modules/.pnpm/eslint-plugin-prettier@5.2.6_eslint@9.24.0_jiti@1.21.7__prettier@3.5.2/node_modules/eslint-plugin-prettier": { - "version": "5.2.6", - "dev": true, - "license": "MIT", - "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.11.0" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-plugin-prettier" - }, - "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", - "prettier": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } - } - }, - "../../node_modules/.pnpm/eslint@9.24.0_jiti@1.21.7/node_modules/eslint": { - "version": "9.24.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.20.0", - "@eslint/config-helpers": "^0.2.0", - "@eslint/core": "^0.12.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.24.0", - "@eslint/plugin-kit": "^0.2.7", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.3.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "devDependencies": { - "@arethetypeswrong/cli": "^0.17.0", - "@babel/core": "^7.4.3", - "@babel/preset-env": "^7.4.3", - "@cypress/webpack-preprocessor": "^6.0.2", - "@eslint/json": "^0.11.0", - "@trunkio/launcher": "^1.3.0", - "@types/node": "^22.13.14", - "@typescript-eslint/parser": "^8.4.0", - "babel-loader": "^8.0.5", - "c8": "^7.12.0", - "chai": "^4.0.1", - "cheerio": "^0.22.0", - "common-tags": "^1.8.0", - "core-js": "^3.1.3", - "cypress": "^14.1.0", - "ejs": "^3.0.2", - "eslint": "file:.", - "eslint-config-eslint": "file:packages/eslint-config-eslint", - "eslint-plugin-eslint-plugin": "^6.0.0", - "eslint-plugin-expect-type": "^0.6.0", - "eslint-plugin-yml": "^1.14.0", - "eslint-release": "^3.3.0", - "eslint-rule-composer": "^0.3.0", - "eslump": "^3.0.0", - "esprima": "^4.0.1", - "fast-glob": "^3.2.11", - "fs-teardown": "^0.1.3", - "glob": "^10.0.0", - "globals": "^15.0.0", - "got": "^11.8.3", - "gray-matter": "^4.0.3", - "jiti": "^2.1.0", - "knip": "^5.32.0", - "lint-staged": "^11.0.0", - "load-perf": "^0.2.0", - "markdown-it": "^12.2.0", - "markdown-it-container": "^3.0.0", - "marked": "^4.0.8", - "metascraper": "^5.25.7", - "metascraper-description": "^5.25.7", - "metascraper-image": "^5.29.3", - "metascraper-logo": "^5.25.7", - "metascraper-logo-favicon": "^5.25.7", - "metascraper-title": "^5.25.7", - "mocha": "^10.7.3", - "node-polyfill-webpack-plugin": "^1.0.3", - "npm-license": "^0.3.3", - "pirates": "^4.0.5", - "progress": "^2.0.3", - "proxyquire": "^2.0.1", - "recast": "^0.23.0", - "regenerator-runtime": "^0.14.0", - "semver": "^7.5.3", - "shelljs": "^0.9.0", - "sinon": "^11.0.0", - "typescript": "^5.3.3", - "webpack": "^5.23.0", - "webpack-cli": "^4.5.0", - "yorkie": "^2.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "../../node_modules/.pnpm/hono@4.7.7/node_modules/hono": { - "version": "4.7.7", - "license": "MIT", - "devDependencies": { - "@hono/eslint-config": "^1.0.2", - "@hono/node-server": "^1.13.5", - "@types/glob": "^8.1.0", - "@types/jsdom": "^21.1.7", - "@types/node": "20.11.4", - "@types/supertest": "^2.0.16", - "@vitest/coverage-v8": "^3.0.5", - "arg": "^5.0.2", - "bun-types": "^1.1.39", - "esbuild": "^0.15.18", - "eslint": "^9.10.0", - "glob": "^11.0.0", - "jsdom": "^22.1.0", - "msw": "^2.6.0", - "np": "10.2.0", - "prettier": "^2.6.2", - "publint": "^0.1.16", - "supertest": "^6.3.4", - "typescript": "^5.3.3", - "vite-plugin-fastly-js-compute": "^0.4.2", - "vitest": "^3.0.5", - "wrangler": "3.58.0", - "ws": "^8.18.0", - "zod": "^3.23.8" - }, - "engines": { - "node": ">=16.9.0" - } - }, - "../../node_modules/.pnpm/prettier@3.5.2/node_modules/prettier": { - "version": "3.5.2", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "../../node_modules/.pnpm/tsx@4.19.3/node_modules/tsx": { - "version": "4.19.3", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "~0.25.0", - "get-tsconfig": "^4.7.5" - }, - "bin": { - "tsx": "dist/cli.mjs" - }, - "engines": { - "node": ">=18.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - } - }, - "../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript": { - "version": "5.8.3", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "devDependencies": { - "@dprint/formatter": "^0.4.1", - "@dprint/typescript": "0.93.3", - "@esfx/canceltoken": "^1.0.0", - "@eslint/js": "^9.17.0", - "@octokit/rest": "^21.0.2", - "@types/chai": "^4.3.20", - "@types/diff": "^5.2.3", - "@types/minimist": "^1.2.5", - "@types/mocha": "^10.0.10", - "@types/ms": "^0.7.34", - "@types/node": "latest", - "@types/source-map-support": "^0.5.10", - "@types/which": "^3.0.4", - "@typescript-eslint/rule-tester": "^8.18.1", - "@typescript-eslint/type-utils": "^8.18.1", - "@typescript-eslint/utils": "^8.18.1", - "azure-devops-node-api": "^14.1.0", - "c8": "^10.1.3", - "chai": "^4.5.0", - "chalk": "^4.1.2", - "chokidar": "^3.6.0", - "diff": "^5.2.0", - "dprint": "^0.47.6", - "esbuild": "^0.24.0", - "eslint": "^9.17.0", - "eslint-formatter-autolinkable-stylish": "^1.4.0", - "eslint-plugin-regexp": "^2.7.0", - "fast-xml-parser": "^4.5.1", - "glob": "^10.4.5", - "globals": "^15.13.0", - "hereby": "^1.10.0", - "jsonc-parser": "^3.3.1", - "knip": "^5.41.0", - "minimist": "^1.2.8", - "mocha": "^10.8.2", - "mocha-fivemat-progress-reporter": "^0.1.0", - "monocart-coverage-reports": "^2.11.4", - "ms": "^2.1.3", - "playwright": "^1.49.1", - "source-map-support": "^0.5.21", - "tslib": "^2.8.1", - "typescript": "^5.7.2", - "typescript-eslint": "^8.18.1", - "which": "^3.0.1" - }, - "engines": { - "node": ">=14.17" - } - }, - "../../node_modules/.pnpm/viem@2.27.2_bufferutil@4.0.9_typescript@5.8.3_utf-8-validate@5.0.10_zod@3.24.3/node_modules/viem": { - "version": "2.27.2", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "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", - "isows": "1.0.6", - "ox": "0.6.9", - "ws": "8.18.1" - }, - "peerDependencies": { - "typescript": ">=5.0.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "../../node_modules/.pnpm/vite-tsconfig-paths@5.1.4_typescript@5.8.3_vite@6.3.2_@types+node@22.14.1_jiti@1.21.7_tsx@4.19.3_yaml@2.7.1_/node_modules/vite-tsconfig-paths": { - "version": "5.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.1.1", - "globrex": "^0.1.2", - "tsconfck": "^3.0.3" - }, - "devDependencies": { - "@alloc/fast-rimraf": "^1.0.8", - "@types/debug": "^4.1.5", - "@types/globrex": "^0.1.0", - "@types/node": "^22.2.0", - "esbuild": "^0.11.12", - "execa": "^9.5.1", - "klona": "^2.0.4", - "prettier": "^2.8.7", - "rollup": "^2.45.2", - "tsup": "^6.5.0", - "typescript": "^5.7.2", - "vite": "^6.0.2", - "vite-tsconfig-paths": "link:.", - "vitest": "^2.1.8" - }, - "peerDependencies": { - "vite": "*" - }, - "peerDependenciesMeta": { - "vite": { - "optional": true - } - } - }, - "../../node_modules/.pnpm/vite@6.3.2_@types+node@22.14.1_jiti@1.21.7_tsx@4.19.3_yaml@2.7.1/node_modules/vite": { - "version": "6.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.25.0", - "fdir": "^6.4.3", - "picomatch": "^4.0.2", - "postcss": "^8.5.3", - "rollup": "^4.34.9", - "tinyglobby": "^0.2.12" - }, - "bin": { - "vite": "bin/vite.js" - }, - "devDependencies": { - "@ampproject/remapping": "^2.3.0", - "@babel/parser": "^7.27.0", - "@jridgewell/trace-mapping": "^0.3.25", - "@polka/compression": "^1.0.0-next.25", - "@rollup/plugin-alias": "^5.1.1", - "@rollup/plugin-commonjs": "^28.0.3", - "@rollup/plugin-dynamic-import-vars": "2.1.4", - "@rollup/plugin-json": "^6.1.0", - "@rollup/plugin-node-resolve": "16.0.1", - "@rollup/pluginutils": "^5.1.4", - "@types/escape-html": "^1.0.4", - "@types/pnpapi": "^0.0.5", - "artichokie": "^0.3.1", - "cac": "^6.7.14", - "chokidar": "^3.6.0", - "connect": "^3.7.0", - "convert-source-map": "^2.0.0", - "cors": "^2.8.5", - "cross-spawn": "^7.0.6", - "debug": "^4.4.0", - "dep-types": "link:./src/types", - "dotenv": "^16.5.0", - "dotenv-expand": "^12.0.2", - "es-module-lexer": "^1.6.0", - "escape-html": "^1.0.3", - "estree-walker": "^3.0.3", - "etag": "^1.8.1", - "http-proxy": "^1.18.1", - "launch-editor-middleware": "^2.10.0", - "lightningcss": "^1.29.3", - "magic-string": "^0.30.17", - "mlly": "^1.7.4", - "mrmime": "^2.0.1", - "nanoid": "^5.1.5", - "open": "^10.1.1", - "parse5": "^7.2.1", - "pathe": "^2.0.3", - "periscopic": "^4.0.2", - "picocolors": "^1.1.1", - "postcss-import": "^16.1.0", - "postcss-load-config": "^6.0.1", - "postcss-modules": "^6.0.1", - "resolve.exports": "^2.0.3", - "rollup-plugin-dts": "^6.2.1", - "rollup-plugin-esbuild": "^6.2.1", - "rollup-plugin-license": "^3.6.0", - "sass": "^1.86.3", - "sass-embedded": "^1.86.3", - "sirv": "^3.0.1", - "source-map-support": "^0.5.21", - "strip-literal": "^3.0.0", - "terser": "^5.39.0", - "tsconfck": "^3.1.5", - "tslib": "^2.8.1", - "types": "link:./types", - "ufo": "^1.6.1", - "ws": "^8.18.1" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "jiti": ">=1.21.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "../../node_modules/.pnpm/vitest@3.1.1_@types+node@22.14.1_jiti@1.21.7_tsx@4.19.3_yaml@2.7.1/node_modules/vitest": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/expect": "3.1.1", - "@vitest/mocker": "3.1.1", - "@vitest/pretty-format": "^3.1.1", - "@vitest/runner": "3.1.1", - "@vitest/snapshot": "3.1.1", - "@vitest/spy": "3.1.1", - "@vitest/utils": "3.1.1", - "chai": "^5.2.0", - "debug": "^4.4.0", - "expect-type": "^1.2.0", - "magic-string": "^0.30.17", - "pathe": "^2.0.3", - "std-env": "^3.8.1", - "tinybench": "^2.9.0", - "tinyexec": "^0.3.2", - "tinypool": "^1.0.2", - "tinyrainbow": "^2.0.0", - "vite": "^5.0.0 || ^6.0.0", - "vite-node": "3.1.1", - "why-is-node-running": "^2.3.0" - }, - "bin": { - "vitest": "vitest.mjs" - }, - "devDependencies": { - "@ampproject/remapping": "^2.3.0", - "@antfu/install-pkg": "^1.0.0", - "@edge-runtime/vm": "^5.0.0", - "@sinonjs/fake-timers": "14.0.0", - "@types/debug": "^4.1.12", - "@types/estree": "^1.0.7", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/jsdom": "^21.1.7", - "@types/micromatch": "^4.0.9", - "@types/node": "^22.13.13", - "@types/prompts": "^2.4.9", - "@types/sinonjs__fake-timers": "^8.1.5", - "acorn-walk": "^8.3.4", - "birpc": "0.2.19", - "cac": "^6.7.14", - "chai-subset": "^1.6.0", - "find-up": "^6.3.0", - "flatted": "^3.3.3", - "get-tsconfig": "^4.10.0", - "happy-dom": "^17.4.4", - "jsdom": "^26.0.0", - "local-pkg": "^1.1.1", - "micromatch": "^4.0.8", - "pretty-format": "^29.7.0", - "prompts": "^2.4.2", - "strip-literal": "^3.0.0", - "tinyglobby": "^0.2.12", - "ws": "^8.18.1" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@types/debug": "^4.1.12", - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.1.1", - "@vitest/ui": "3.1.1", - "happy-dom": "*", - "jsdom": "*" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@types/debug": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - } - } - }, - "../../node_modules/.pnpm/zod@3.24.3/node_modules/zod": { - "version": "3.24.3", - "license": "MIT", - "devDependencies": { - "@babel/core": "^7.22.5", - "@babel/preset-env": "^7.22.5", - "@babel/preset-typescript": "^7.22.5", - "@jest/globals": "^29.4.3", - "@rollup/plugin-typescript": "^8.2.0", - "@standard-schema/spec": "^1.0.0-beta.4", - "@swc/core": "^1.3.66", - "@swc/jest": "^0.2.26", - "@types/benchmark": "^2.1.0", - "@types/jest": "^29.2.2", - "@types/node": "14", - "@typescript-eslint/eslint-plugin": "^5.15.0", - "@typescript-eslint/parser": "^5.15.0", - "babel-jest": "^29.5.0", - "benchmark": "^2.1.4", - "dependency-cruiser": "^9.19.0", - "eslint": "^8.11.0", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-ban": "^1.6.0", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-simple-import-sort": "^7.0.0", - "eslint-plugin-unused-imports": "^2.0.0", - "husky": "^7.0.4", - "jest": "^29.3.1", - "lint-staged": "^12.3.7", - "netlify-cli": "^17.26.2", - "nodemon": "^2.0.15", - "prettier": "^2.6.0", - "pretty-quick": "^3.1.3", - "rollup": "^2.70.1", - "ts-jest": "^29.1.0", - "ts-morph": "^14.0.0", - "ts-node": "^10.9.1", - "tslib": "^2.3.1", - "tsx": "^3.8.0", - "typescript": "^5.0.0", - "vitest": "^0.32.2" - }, - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/@hono/node-server": { - "resolved": "../../node_modules/.pnpm/@hono+node-server@1.14.1_hono@4.7.7/node_modules/@hono/node-server", - "link": true - }, - "node_modules/@types/node": { - "resolved": "../../node_modules/.pnpm/@types+node@22.14.1/node_modules/@types/node", - "link": true - }, - "node_modules/dotenv": { - "resolved": "../../node_modules/.pnpm/dotenv@16.5.0/node_modules/dotenv", - "link": true - }, - "node_modules/hono": { - "resolved": "../../node_modules/.pnpm/hono@4.7.7/node_modules/hono", - "link": true - }, - "node_modules/tsx": { - "resolved": "../../node_modules/.pnpm/tsx@4.19.3/node_modules/tsx", - "link": true - }, - "node_modules/viem": { - "resolved": "../../node_modules/.pnpm/viem@2.27.2_bufferutil@4.0.9_typescript@5.8.3_utf-8-validate@5.0.10_zod@3.24.3/node_modules/viem", - "link": true - }, - "node_modules/x402": { - "resolved": "../../../../typescript/packages/x402", - "link": true - } - } -} \ No newline at end of file diff --git a/examples/typescript/agent/.env-local b/examples/typescript/legacy/agent/.env-local similarity index 100% rename from examples/typescript/agent/.env-local rename to examples/typescript/legacy/agent/.env-local diff --git a/examples/typescript/clients/cdp-sdk/.prettierignore b/examples/typescript/legacy/agent/.prettierignore similarity index 100% rename from examples/typescript/clients/cdp-sdk/.prettierignore rename to examples/typescript/legacy/agent/.prettierignore diff --git a/examples/typescript/clients/cdp-sdk/.prettierrc b/examples/typescript/legacy/agent/.prettierrc similarity index 100% rename from examples/typescript/clients/cdp-sdk/.prettierrc rename to examples/typescript/legacy/agent/.prettierrc diff --git a/examples/typescript/agent/README.md b/examples/typescript/legacy/agent/README.md similarity index 100% rename from examples/typescript/agent/README.md rename to examples/typescript/legacy/agent/README.md diff --git a/examples/typescript/clients/axios/eslint.config.js b/examples/typescript/legacy/agent/eslint.config.js similarity index 100% rename from examples/typescript/clients/axios/eslint.config.js rename to examples/typescript/legacy/agent/eslint.config.js diff --git a/examples/typescript/agent/index.ts b/examples/typescript/legacy/agent/index.ts similarity index 100% rename from examples/typescript/agent/index.ts rename to examples/typescript/legacy/agent/index.ts diff --git a/examples/typescript/agent/package.json b/examples/typescript/legacy/agent/package.json similarity index 100% rename from examples/typescript/agent/package.json rename to examples/typescript/legacy/agent/package.json diff --git a/examples/typescript/agent/tsconfig.json b/examples/typescript/legacy/agent/tsconfig.json similarity index 100% rename from examples/typescript/agent/tsconfig.json rename to examples/typescript/legacy/agent/tsconfig.json diff --git a/examples/typescript/clients/axios/.env-local b/examples/typescript/legacy/clients/axios/.env-local similarity index 100% rename from examples/typescript/clients/axios/.env-local rename to examples/typescript/legacy/clients/axios/.env-local diff --git a/examples/typescript/clients/chainlink-vrf-nft/.prettierignore b/examples/typescript/legacy/clients/axios/.prettierignore similarity index 100% rename from examples/typescript/clients/chainlink-vrf-nft/.prettierignore rename to examples/typescript/legacy/clients/axios/.prettierignore diff --git a/examples/typescript/clients/chainlink-vrf-nft/.prettierrc b/examples/typescript/legacy/clients/axios/.prettierrc similarity index 100% rename from examples/typescript/clients/chainlink-vrf-nft/.prettierrc rename to examples/typescript/legacy/clients/axios/.prettierrc diff --git a/examples/typescript/clients/axios/README.md b/examples/typescript/legacy/clients/axios/README.md similarity index 100% rename from examples/typescript/clients/axios/README.md rename to examples/typescript/legacy/clients/axios/README.md diff --git a/examples/typescript/clients/cdp-sdk/eslint.config.js b/examples/typescript/legacy/clients/axios/eslint.config.js similarity index 100% rename from examples/typescript/clients/cdp-sdk/eslint.config.js rename to examples/typescript/legacy/clients/axios/eslint.config.js diff --git a/examples/typescript/clients/axios/index.ts b/examples/typescript/legacy/clients/axios/index.ts similarity index 95% rename from examples/typescript/clients/axios/index.ts rename to examples/typescript/legacy/clients/axios/index.ts index 04af86ef3..0c71ec727 100644 --- a/examples/typescript/clients/axios/index.ts +++ b/examples/typescript/legacy/clients/axios/index.ts @@ -24,7 +24,7 @@ if (!baseURL || !privateKey || !endpointPath) { */ async function main(): Promise { // const signer = await createSigner("solana-devnet", privateKey); // uncomment for solana - const signer = await createSigner("base-sepolia", privateKey); + const signer = await createSigner("solana", privateKey); const api = withPaymentInterceptor( axios.create({ diff --git a/examples/typescript/clients/axios/multi-network-signer.ts b/examples/typescript/legacy/clients/axios/multi-network-signer.ts similarity index 100% rename from examples/typescript/clients/axios/multi-network-signer.ts rename to examples/typescript/legacy/clients/axios/multi-network-signer.ts diff --git a/examples/typescript/clients/axios/package.json b/examples/typescript/legacy/clients/axios/package.json similarity index 100% rename from examples/typescript/clients/axios/package.json rename to examples/typescript/legacy/clients/axios/package.json diff --git a/examples/typescript/clients/fetch/tsconfig.json b/examples/typescript/legacy/clients/axios/tsconfig.json similarity index 100% rename from examples/typescript/clients/fetch/tsconfig.json rename to examples/typescript/legacy/clients/axios/tsconfig.json diff --git a/examples/typescript/clients/cdp-sdk/.env-local b/examples/typescript/legacy/clients/cdp-sdk/.env-local similarity index 100% rename from examples/typescript/clients/cdp-sdk/.env-local rename to examples/typescript/legacy/clients/cdp-sdk/.env-local diff --git a/examples/typescript/clients/fetch/.prettierignore b/examples/typescript/legacy/clients/cdp-sdk/.prettierignore similarity index 100% rename from examples/typescript/clients/fetch/.prettierignore rename to examples/typescript/legacy/clients/cdp-sdk/.prettierignore diff --git a/examples/typescript/clients/fetch/.prettierrc b/examples/typescript/legacy/clients/cdp-sdk/.prettierrc similarity index 100% rename from examples/typescript/clients/fetch/.prettierrc rename to examples/typescript/legacy/clients/cdp-sdk/.prettierrc diff --git a/examples/typescript/clients/cdp-sdk/README.md b/examples/typescript/legacy/clients/cdp-sdk/README.md similarity index 100% rename from examples/typescript/clients/cdp-sdk/README.md rename to examples/typescript/legacy/clients/cdp-sdk/README.md diff --git a/examples/typescript/clients/fetch/eslint.config.js b/examples/typescript/legacy/clients/cdp-sdk/eslint.config.js similarity index 100% rename from examples/typescript/clients/fetch/eslint.config.js rename to examples/typescript/legacy/clients/cdp-sdk/eslint.config.js diff --git a/examples/typescript/clients/cdp-sdk/index.ts b/examples/typescript/legacy/clients/cdp-sdk/index.ts similarity index 100% rename from examples/typescript/clients/cdp-sdk/index.ts rename to examples/typescript/legacy/clients/cdp-sdk/index.ts diff --git a/examples/typescript/clients/cdp-sdk/package.json b/examples/typescript/legacy/clients/cdp-sdk/package.json similarity index 100% rename from examples/typescript/clients/cdp-sdk/package.json rename to examples/typescript/legacy/clients/cdp-sdk/package.json diff --git a/examples/typescript/clients/cdp-sdk/tsconfig.json b/examples/typescript/legacy/clients/cdp-sdk/tsconfig.json similarity index 100% rename from examples/typescript/clients/cdp-sdk/tsconfig.json rename to examples/typescript/legacy/clients/cdp-sdk/tsconfig.json diff --git a/examples/typescript/clients/chainlink-vrf-nft/.env-local b/examples/typescript/legacy/clients/chainlink-vrf-nft/.env-local similarity index 100% rename from examples/typescript/clients/chainlink-vrf-nft/.env-local rename to examples/typescript/legacy/clients/chainlink-vrf-nft/.env-local diff --git a/examples/typescript/discovery/.prettierignore b/examples/typescript/legacy/clients/chainlink-vrf-nft/.prettierignore similarity index 100% rename from examples/typescript/discovery/.prettierignore rename to examples/typescript/legacy/clients/chainlink-vrf-nft/.prettierignore diff --git a/examples/typescript/discovery/.prettierrc b/examples/typescript/legacy/clients/chainlink-vrf-nft/.prettierrc similarity index 100% rename from examples/typescript/discovery/.prettierrc rename to examples/typescript/legacy/clients/chainlink-vrf-nft/.prettierrc diff --git a/examples/typescript/clients/chainlink-vrf-nft/README.md b/examples/typescript/legacy/clients/chainlink-vrf-nft/README.md similarity index 100% rename from examples/typescript/clients/chainlink-vrf-nft/README.md rename to examples/typescript/legacy/clients/chainlink-vrf-nft/README.md diff --git a/examples/typescript/clients/chainlink-vrf-nft/client.ts b/examples/typescript/legacy/clients/chainlink-vrf-nft/client.ts similarity index 100% rename from examples/typescript/clients/chainlink-vrf-nft/client.ts rename to examples/typescript/legacy/clients/chainlink-vrf-nft/client.ts diff --git a/examples/typescript/clients/chainlink-vrf-nft/package.json b/examples/typescript/legacy/clients/chainlink-vrf-nft/package.json similarity index 90% rename from examples/typescript/clients/chainlink-vrf-nft/package.json rename to examples/typescript/legacy/clients/chainlink-vrf-nft/package.json index d075d1fe5..08a41c3f2 100644 --- a/examples/typescript/clients/chainlink-vrf-nft/package.json +++ b/examples/typescript/legacy/clients/chainlink-vrf-nft/package.json @@ -13,7 +13,7 @@ "hono": "^4.7.2", "@hono/node-server": "^1.13.8", "viem": "^2.23.5", - "x402": "file:../../../../typescript/packages/x402", + "x402": "workspace:*", "axios": "^1.7.9", "x402-axios": "workspace:*" }, diff --git a/examples/typescript/clients/chainlink-vrf-nft/resource.ts b/examples/typescript/legacy/clients/chainlink-vrf-nft/resource.ts similarity index 100% rename from examples/typescript/clients/chainlink-vrf-nft/resource.ts rename to examples/typescript/legacy/clients/chainlink-vrf-nft/resource.ts diff --git a/examples/typescript/clients/fetch/.env-local b/examples/typescript/legacy/clients/fetch/.env-local similarity index 100% rename from examples/typescript/clients/fetch/.env-local rename to examples/typescript/legacy/clients/fetch/.env-local diff --git a/examples/typescript/facilitator/.prettierignore b/examples/typescript/legacy/clients/fetch/.prettierignore similarity index 100% rename from examples/typescript/facilitator/.prettierignore rename to examples/typescript/legacy/clients/fetch/.prettierignore diff --git a/examples/typescript/facilitator/.prettierrc b/examples/typescript/legacy/clients/fetch/.prettierrc similarity index 100% rename from examples/typescript/facilitator/.prettierrc rename to examples/typescript/legacy/clients/fetch/.prettierrc diff --git a/examples/typescript/legacy/clients/fetch/README.md b/examples/typescript/legacy/clients/fetch/README.md new file mode 100644 index 000000000..f04ed5516 --- /dev/null +++ b/examples/typescript/legacy/clients/fetch/README.md @@ -0,0 +1,75 @@ +# x402-fetch Example Client + +This is an example client that demonstrates how to use the `x402-fetch` package to make HTTP requests to endpoints protected by the x402 payment protocol. + +## Prerequisites + +- Node.js v20+ (install via [nvm](https://github.com/nvm-sh/nvm)) +- pnpm v10 (install via [pnpm.io/installation](https://pnpm.io/installation)) +- A running x402 server (you can use the example express server at `examples/typescript/servers/express`) +- A valid Ethereum private key for making payments + +## Setup + +1. Install and build all packages from the typescript examples root: +```bash +cd ../../ +pnpm install +pnpm build +cd clients/fetch +``` + +2. Copy `.env-local` to `.env` and add your Ethereum private key: +```bash +cp .env-local .env +``` + +3. Start the example client: +```bash +pnpm dev +``` + +## How It Works + +The example demonstrates how to: +1. Create a wallet client using viem +2. Wrap the native fetch function with x402 payment handling +3. Make a request to a paid endpoint +4. Handle the response or any errors + +## Example Code + +```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 { RESOURCE_SERVER_URL, PRIVATE_KEY, ENDPOINT_PATH } = process.env; + +// Create wallet client +const account = privateKeyToAccount(PRIVATE_KEY as `0x${string}`); +const client = createWalletClient({ + account, + transport: http(), + chain: baseSepolia, +}); + +// Wrap fetch with payment handling +const fetchWithPay = wrapFetchWithPayment(fetch, client); + +// Make request to paid endpoint +fetchWithPay(`${RESOURCE_SERVER_URL}${ENDPOINT_PATH}`, { + method: "GET", +}) + .then(async response => { + const body = await response.json(); + console.log(body); + }) + .catch(error => { + console.error(error.response?.data?.error); + }); +``` diff --git a/examples/typescript/discovery/eslint.config.js b/examples/typescript/legacy/clients/fetch/eslint.config.js similarity index 100% rename from examples/typescript/discovery/eslint.config.js rename to examples/typescript/legacy/clients/fetch/eslint.config.js diff --git a/examples/typescript/clients/fetch/index.ts b/examples/typescript/legacy/clients/fetch/index.ts similarity index 100% rename from examples/typescript/clients/fetch/index.ts rename to examples/typescript/legacy/clients/fetch/index.ts diff --git a/examples/typescript/clients/fetch/multi-network-signer.ts b/examples/typescript/legacy/clients/fetch/multi-network-signer.ts similarity index 100% rename from examples/typescript/clients/fetch/multi-network-signer.ts rename to examples/typescript/legacy/clients/fetch/multi-network-signer.ts diff --git a/examples/typescript/clients/fetch/package.json b/examples/typescript/legacy/clients/fetch/package.json similarity index 100% rename from examples/typescript/clients/fetch/package.json rename to examples/typescript/legacy/clients/fetch/package.json diff --git a/examples/typescript/discovery/tsconfig.json b/examples/typescript/legacy/clients/fetch/tsconfig.json similarity index 100% rename from examples/typescript/discovery/tsconfig.json rename to examples/typescript/legacy/clients/fetch/tsconfig.json diff --git a/examples/typescript/fullstack/mainnet/.prettierignore b/examples/typescript/legacy/discovery/.prettierignore similarity index 100% rename from examples/typescript/fullstack/mainnet/.prettierignore rename to examples/typescript/legacy/discovery/.prettierignore diff --git a/examples/typescript/fullstack/mainnet/.prettierrc b/examples/typescript/legacy/discovery/.prettierrc similarity index 100% rename from examples/typescript/fullstack/mainnet/.prettierrc rename to examples/typescript/legacy/discovery/.prettierrc diff --git a/examples/typescript/discovery/README.md b/examples/typescript/legacy/discovery/README.md similarity index 100% rename from examples/typescript/discovery/README.md rename to examples/typescript/legacy/discovery/README.md diff --git a/typescript/packages/x402-axios/eslint.config.js b/examples/typescript/legacy/discovery/eslint.config.js similarity index 100% rename from typescript/packages/x402-axios/eslint.config.js rename to examples/typescript/legacy/discovery/eslint.config.js diff --git a/examples/typescript/discovery/index.ts b/examples/typescript/legacy/discovery/index.ts similarity index 100% rename from examples/typescript/discovery/index.ts rename to examples/typescript/legacy/discovery/index.ts diff --git a/examples/typescript/discovery/package.json b/examples/typescript/legacy/discovery/package.json similarity index 100% rename from examples/typescript/discovery/package.json rename to examples/typescript/legacy/discovery/package.json diff --git a/examples/typescript/facilitator/tsconfig.json b/examples/typescript/legacy/discovery/tsconfig.json similarity index 100% rename from examples/typescript/facilitator/tsconfig.json rename to examples/typescript/legacy/discovery/tsconfig.json diff --git a/examples/typescript/dynamic_agent/.env-local b/examples/typescript/legacy/dynamic_agent/.env-local similarity index 100% rename from examples/typescript/dynamic_agent/.env-local rename to examples/typescript/legacy/dynamic_agent/.env-local diff --git a/examples/typescript/dynamic_agent/.gitignore b/examples/typescript/legacy/dynamic_agent/.gitignore similarity index 100% rename from examples/typescript/dynamic_agent/.gitignore rename to examples/typescript/legacy/dynamic_agent/.gitignore diff --git a/examples/typescript/dynamic_agent/README.md b/examples/typescript/legacy/dynamic_agent/README.md similarity index 100% rename from examples/typescript/dynamic_agent/README.md rename to examples/typescript/legacy/dynamic_agent/README.md diff --git a/examples/typescript/dynamic_agent/agent.ts b/examples/typescript/legacy/dynamic_agent/agent.ts similarity index 100% rename from examples/typescript/dynamic_agent/agent.ts rename to examples/typescript/legacy/dynamic_agent/agent.ts diff --git a/examples/typescript/dynamic_agent/discover_server.ts b/examples/typescript/legacy/dynamic_agent/discover_server.ts similarity index 100% rename from examples/typescript/dynamic_agent/discover_server.ts rename to examples/typescript/legacy/dynamic_agent/discover_server.ts diff --git a/examples/typescript/dynamic_agent/package-lock.json b/examples/typescript/legacy/dynamic_agent/package-lock.json similarity index 100% rename from examples/typescript/dynamic_agent/package-lock.json rename to examples/typescript/legacy/dynamic_agent/package-lock.json diff --git a/examples/typescript/dynamic_agent/package.json b/examples/typescript/legacy/dynamic_agent/package.json similarity index 100% rename from examples/typescript/dynamic_agent/package.json rename to examples/typescript/legacy/dynamic_agent/package.json diff --git a/examples/typescript/dynamic_agent/tsconfig.json b/examples/typescript/legacy/dynamic_agent/tsconfig.json similarity index 100% rename from examples/typescript/dynamic_agent/tsconfig.json rename to examples/typescript/legacy/dynamic_agent/tsconfig.json diff --git a/examples/typescript/facilitator/.env-local b/examples/typescript/legacy/facilitator/.env-local similarity index 100% rename from examples/typescript/facilitator/.env-local rename to examples/typescript/legacy/facilitator/.env-local diff --git a/examples/typescript/fullstack/next/.prettierignore b/examples/typescript/legacy/facilitator/.prettierignore similarity index 100% rename from examples/typescript/fullstack/next/.prettierignore rename to examples/typescript/legacy/facilitator/.prettierignore diff --git a/examples/typescript/fullstack/next/.prettierrc b/examples/typescript/legacy/facilitator/.prettierrc similarity index 100% rename from examples/typescript/fullstack/next/.prettierrc rename to examples/typescript/legacy/facilitator/.prettierrc diff --git a/examples/typescript/facilitator/README.md b/examples/typescript/legacy/facilitator/README.md similarity index 100% rename from examples/typescript/facilitator/README.md rename to examples/typescript/legacy/facilitator/README.md diff --git a/examples/typescript/servers/advanced/eslint.config.js b/examples/typescript/legacy/facilitator/eslint.config.js similarity index 100% rename from examples/typescript/servers/advanced/eslint.config.js rename to examples/typescript/legacy/facilitator/eslint.config.js diff --git a/examples/typescript/facilitator/index.ts b/examples/typescript/legacy/facilitator/index.ts similarity index 100% rename from examples/typescript/facilitator/index.ts rename to examples/typescript/legacy/facilitator/index.ts diff --git a/examples/typescript/facilitator/package.json b/examples/typescript/legacy/facilitator/package.json similarity index 100% rename from examples/typescript/facilitator/package.json rename to examples/typescript/legacy/facilitator/package.json diff --git a/examples/typescript/servers/advanced/tsconfig.json b/examples/typescript/legacy/facilitator/tsconfig.json similarity index 100% rename from examples/typescript/servers/advanced/tsconfig.json rename to examples/typescript/legacy/facilitator/tsconfig.json diff --git a/examples/typescript/fullstack/auth_based_pricing/.env-local b/examples/typescript/legacy/fullstack/auth_based_pricing/.env-local similarity index 100% rename from examples/typescript/fullstack/auth_based_pricing/.env-local rename to examples/typescript/legacy/fullstack/auth_based_pricing/.env-local diff --git a/examples/typescript/fullstack/auth_based_pricing/.gitignore b/examples/typescript/legacy/fullstack/auth_based_pricing/.gitignore similarity index 100% rename from examples/typescript/fullstack/auth_based_pricing/.gitignore rename to examples/typescript/legacy/fullstack/auth_based_pricing/.gitignore diff --git a/examples/typescript/fullstack/auth_based_pricing/README.md b/examples/typescript/legacy/fullstack/auth_based_pricing/README.md similarity index 100% rename from examples/typescript/fullstack/auth_based_pricing/README.md rename to examples/typescript/legacy/fullstack/auth_based_pricing/README.md diff --git a/examples/typescript/fullstack/auth_based_pricing/backend.ts b/examples/typescript/legacy/fullstack/auth_based_pricing/backend.ts similarity index 100% rename from examples/typescript/fullstack/auth_based_pricing/backend.ts rename to examples/typescript/legacy/fullstack/auth_based_pricing/backend.ts diff --git a/examples/typescript/fullstack/auth_based_pricing/client.ts b/examples/typescript/legacy/fullstack/auth_based_pricing/client.ts similarity index 100% rename from examples/typescript/fullstack/auth_based_pricing/client.ts rename to examples/typescript/legacy/fullstack/auth_based_pricing/client.ts diff --git a/examples/typescript/fullstack/auth_based_pricing/package.json b/examples/typescript/legacy/fullstack/auth_based_pricing/package.json similarity index 100% rename from examples/typescript/fullstack/auth_based_pricing/package.json rename to examples/typescript/legacy/fullstack/auth_based_pricing/package.json diff --git a/examples/typescript/fullstack/auth_based_pricing/tsconfig.json b/examples/typescript/legacy/fullstack/auth_based_pricing/tsconfig.json similarity index 100% rename from examples/typescript/fullstack/auth_based_pricing/tsconfig.json rename to examples/typescript/legacy/fullstack/auth_based_pricing/tsconfig.json diff --git a/examples/typescript/fullstack/browser-wallet-example/.gitignore b/examples/typescript/legacy/fullstack/browser-wallet-example/.gitignore similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/.gitignore rename to examples/typescript/legacy/fullstack/browser-wallet-example/.gitignore diff --git a/examples/typescript/fullstack/browser-wallet-example/README.md b/examples/typescript/legacy/fullstack/browser-wallet-example/README.md similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/README.md rename to examples/typescript/legacy/fullstack/browser-wallet-example/README.md diff --git a/examples/typescript/fullstack/browser-wallet-example/client/index.html b/examples/typescript/legacy/fullstack/browser-wallet-example/client/index.html similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/client/index.html rename to examples/typescript/legacy/fullstack/browser-wallet-example/client/index.html diff --git a/examples/typescript/fullstack/browser-wallet-example/client/package-lock.json b/examples/typescript/legacy/fullstack/browser-wallet-example/client/package-lock.json similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/client/package-lock.json rename to examples/typescript/legacy/fullstack/browser-wallet-example/client/package-lock.json diff --git a/examples/typescript/fullstack/browser-wallet-example/client/package.json b/examples/typescript/legacy/fullstack/browser-wallet-example/client/package.json similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/client/package.json rename to examples/typescript/legacy/fullstack/browser-wallet-example/client/package.json diff --git a/examples/typescript/fullstack/browser-wallet-example/client/src/App.css b/examples/typescript/legacy/fullstack/browser-wallet-example/client/src/App.css similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/client/src/App.css rename to examples/typescript/legacy/fullstack/browser-wallet-example/client/src/App.css diff --git a/examples/typescript/fullstack/browser-wallet-example/client/src/App.tsx b/examples/typescript/legacy/fullstack/browser-wallet-example/client/src/App.tsx similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/client/src/App.tsx rename to examples/typescript/legacy/fullstack/browser-wallet-example/client/src/App.tsx diff --git a/examples/typescript/fullstack/browser-wallet-example/client/src/components/WalletConnect.tsx b/examples/typescript/legacy/fullstack/browser-wallet-example/client/src/components/WalletConnect.tsx similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/client/src/components/WalletConnect.tsx rename to examples/typescript/legacy/fullstack/browser-wallet-example/client/src/components/WalletConnect.tsx diff --git a/examples/typescript/fullstack/browser-wallet-example/client/src/contexts/WalletContext.tsx b/examples/typescript/legacy/fullstack/browser-wallet-example/client/src/contexts/WalletContext.tsx similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/client/src/contexts/WalletContext.tsx rename to examples/typescript/legacy/fullstack/browser-wallet-example/client/src/contexts/WalletContext.tsx diff --git a/examples/typescript/fullstack/browser-wallet-example/client/src/main.tsx b/examples/typescript/legacy/fullstack/browser-wallet-example/client/src/main.tsx similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/client/src/main.tsx rename to examples/typescript/legacy/fullstack/browser-wallet-example/client/src/main.tsx diff --git a/examples/typescript/fullstack/browser-wallet-example/client/src/services/api.ts b/examples/typescript/legacy/fullstack/browser-wallet-example/client/src/services/api.ts similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/client/src/services/api.ts rename to examples/typescript/legacy/fullstack/browser-wallet-example/client/src/services/api.ts diff --git a/examples/typescript/fullstack/browser-wallet-example/client/src/types/window.d.ts b/examples/typescript/legacy/fullstack/browser-wallet-example/client/src/types/window.d.ts similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/client/src/types/window.d.ts rename to examples/typescript/legacy/fullstack/browser-wallet-example/client/src/types/window.d.ts diff --git a/examples/typescript/fullstack/browser-wallet-example/client/src/vite-env.d.ts b/examples/typescript/legacy/fullstack/browser-wallet-example/client/src/vite-env.d.ts similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/client/src/vite-env.d.ts rename to examples/typescript/legacy/fullstack/browser-wallet-example/client/src/vite-env.d.ts diff --git a/examples/typescript/fullstack/browser-wallet-example/client/tsconfig.json b/examples/typescript/legacy/fullstack/browser-wallet-example/client/tsconfig.json similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/client/tsconfig.json rename to examples/typescript/legacy/fullstack/browser-wallet-example/client/tsconfig.json diff --git a/examples/typescript/fullstack/browser-wallet-example/client/vite.config.ts b/examples/typescript/legacy/fullstack/browser-wallet-example/client/vite.config.ts similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/client/vite.config.ts rename to examples/typescript/legacy/fullstack/browser-wallet-example/client/vite.config.ts diff --git a/examples/typescript/fullstack/browser-wallet-example/package-lock.json b/examples/typescript/legacy/fullstack/browser-wallet-example/package-lock.json similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/package-lock.json rename to examples/typescript/legacy/fullstack/browser-wallet-example/package-lock.json diff --git a/examples/typescript/fullstack/browser-wallet-example/package.json b/examples/typescript/legacy/fullstack/browser-wallet-example/package.json similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/package.json rename to examples/typescript/legacy/fullstack/browser-wallet-example/package.json diff --git a/examples/typescript/fullstack/browser-wallet-example/server/.env.example b/examples/typescript/legacy/fullstack/browser-wallet-example/server/.env.example similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/server/.env.example rename to examples/typescript/legacy/fullstack/browser-wallet-example/server/.env.example diff --git a/examples/typescript/fullstack/browser-wallet-example/server/README.md b/examples/typescript/legacy/fullstack/browser-wallet-example/server/README.md similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/server/README.md rename to examples/typescript/legacy/fullstack/browser-wallet-example/server/README.md diff --git a/examples/typescript/fullstack/browser-wallet-example/server/index.ts b/examples/typescript/legacy/fullstack/browser-wallet-example/server/index.ts similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/server/index.ts rename to examples/typescript/legacy/fullstack/browser-wallet-example/server/index.ts diff --git a/examples/typescript/fullstack/browser-wallet-example/server/package-lock.json b/examples/typescript/legacy/fullstack/browser-wallet-example/server/package-lock.json similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/server/package-lock.json rename to examples/typescript/legacy/fullstack/browser-wallet-example/server/package-lock.json diff --git a/examples/typescript/fullstack/browser-wallet-example/server/package.json b/examples/typescript/legacy/fullstack/browser-wallet-example/server/package.json similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/server/package.json rename to examples/typescript/legacy/fullstack/browser-wallet-example/server/package.json diff --git a/examples/typescript/fullstack/browser-wallet-example/server/tsconfig.json b/examples/typescript/legacy/fullstack/browser-wallet-example/server/tsconfig.json similarity index 100% rename from examples/typescript/fullstack/browser-wallet-example/server/tsconfig.json rename to examples/typescript/legacy/fullstack/browser-wallet-example/server/tsconfig.json diff --git a/examples/typescript/fullstack/farcaster-miniapp/.eslintrc.json b/examples/typescript/legacy/fullstack/farcaster-miniapp/.eslintrc.json similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/.eslintrc.json rename to examples/typescript/legacy/fullstack/farcaster-miniapp/.eslintrc.json diff --git a/examples/typescript/fullstack/farcaster-miniapp/.gitignore b/examples/typescript/legacy/fullstack/farcaster-miniapp/.gitignore similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/.gitignore rename to examples/typescript/legacy/fullstack/farcaster-miniapp/.gitignore diff --git a/examples/typescript/fullstack/farcaster-miniapp/.prettierrc b/examples/typescript/legacy/fullstack/farcaster-miniapp/.prettierrc similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/.prettierrc rename to examples/typescript/legacy/fullstack/farcaster-miniapp/.prettierrc diff --git a/examples/typescript/fullstack/farcaster-miniapp/.yarnrc.yml b/examples/typescript/legacy/fullstack/farcaster-miniapp/.yarnrc.yml similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/.yarnrc.yml rename to examples/typescript/legacy/fullstack/farcaster-miniapp/.yarnrc.yml diff --git a/examples/typescript/fullstack/farcaster-miniapp/README.md b/examples/typescript/legacy/fullstack/farcaster-miniapp/README.md similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/README.md rename to examples/typescript/legacy/fullstack/farcaster-miniapp/README.md diff --git a/examples/typescript/fullstack/farcaster-miniapp/app/.well-known/farcaster.json/route.ts b/examples/typescript/legacy/fullstack/farcaster-miniapp/app/.well-known/farcaster.json/route.ts similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/app/.well-known/farcaster.json/route.ts rename to examples/typescript/legacy/fullstack/farcaster-miniapp/app/.well-known/farcaster.json/route.ts diff --git a/examples/typescript/fullstack/farcaster-miniapp/app/api/notify/route.ts b/examples/typescript/legacy/fullstack/farcaster-miniapp/app/api/notify/route.ts similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/app/api/notify/route.ts rename to examples/typescript/legacy/fullstack/farcaster-miniapp/app/api/notify/route.ts diff --git a/examples/typescript/fullstack/farcaster-miniapp/app/api/protected/route.ts b/examples/typescript/legacy/fullstack/farcaster-miniapp/app/api/protected/route.ts similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/app/api/protected/route.ts rename to examples/typescript/legacy/fullstack/farcaster-miniapp/app/api/protected/route.ts diff --git a/examples/typescript/fullstack/farcaster-miniapp/app/api/webhook/route.ts b/examples/typescript/legacy/fullstack/farcaster-miniapp/app/api/webhook/route.ts similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/app/api/webhook/route.ts rename to examples/typescript/legacy/fullstack/farcaster-miniapp/app/api/webhook/route.ts diff --git a/examples/typescript/fullstack/farcaster-miniapp/app/globals.css b/examples/typescript/legacy/fullstack/farcaster-miniapp/app/globals.css similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/app/globals.css rename to examples/typescript/legacy/fullstack/farcaster-miniapp/app/globals.css diff --git a/examples/typescript/fullstack/farcaster-miniapp/app/layout.tsx b/examples/typescript/legacy/fullstack/farcaster-miniapp/app/layout.tsx similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/app/layout.tsx rename to examples/typescript/legacy/fullstack/farcaster-miniapp/app/layout.tsx diff --git a/examples/typescript/fullstack/farcaster-miniapp/app/page.tsx b/examples/typescript/legacy/fullstack/farcaster-miniapp/app/page.tsx similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/app/page.tsx rename to examples/typescript/legacy/fullstack/farcaster-miniapp/app/page.tsx diff --git a/examples/typescript/fullstack/farcaster-miniapp/app/providers.tsx b/examples/typescript/legacy/fullstack/farcaster-miniapp/app/providers.tsx similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/app/providers.tsx rename to examples/typescript/legacy/fullstack/farcaster-miniapp/app/providers.tsx diff --git a/examples/typescript/fullstack/farcaster-miniapp/app/theme.css b/examples/typescript/legacy/fullstack/farcaster-miniapp/app/theme.css similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/app/theme.css rename to examples/typescript/legacy/fullstack/farcaster-miniapp/app/theme.css diff --git a/examples/typescript/fullstack/farcaster-miniapp/env.example b/examples/typescript/legacy/fullstack/farcaster-miniapp/env.example similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/env.example rename to examples/typescript/legacy/fullstack/farcaster-miniapp/env.example diff --git a/examples/typescript/fullstack/farcaster-miniapp/lib/notification-client.ts b/examples/typescript/legacy/fullstack/farcaster-miniapp/lib/notification-client.ts similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/lib/notification-client.ts rename to examples/typescript/legacy/fullstack/farcaster-miniapp/lib/notification-client.ts diff --git a/examples/typescript/fullstack/farcaster-miniapp/lib/notification.ts b/examples/typescript/legacy/fullstack/farcaster-miniapp/lib/notification.ts similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/lib/notification.ts rename to examples/typescript/legacy/fullstack/farcaster-miniapp/lib/notification.ts diff --git a/examples/typescript/fullstack/farcaster-miniapp/lib/redis.ts b/examples/typescript/legacy/fullstack/farcaster-miniapp/lib/redis.ts similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/lib/redis.ts rename to examples/typescript/legacy/fullstack/farcaster-miniapp/lib/redis.ts diff --git a/examples/typescript/fullstack/farcaster-miniapp/middleware.ts b/examples/typescript/legacy/fullstack/farcaster-miniapp/middleware.ts similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/middleware.ts rename to examples/typescript/legacy/fullstack/farcaster-miniapp/middleware.ts diff --git a/examples/typescript/fullstack/farcaster-miniapp/next.config.mjs b/examples/typescript/legacy/fullstack/farcaster-miniapp/next.config.mjs similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/next.config.mjs rename to examples/typescript/legacy/fullstack/farcaster-miniapp/next.config.mjs diff --git a/examples/typescript/fullstack/farcaster-miniapp/package.json b/examples/typescript/legacy/fullstack/farcaster-miniapp/package.json similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/package.json rename to examples/typescript/legacy/fullstack/farcaster-miniapp/package.json diff --git a/examples/typescript/fullstack/farcaster-miniapp/postcss.config.mjs b/examples/typescript/legacy/fullstack/farcaster-miniapp/postcss.config.mjs similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/postcss.config.mjs rename to examples/typescript/legacy/fullstack/farcaster-miniapp/postcss.config.mjs diff --git a/examples/typescript/fullstack/farcaster-miniapp/public/hero.png b/examples/typescript/legacy/fullstack/farcaster-miniapp/public/hero.png similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/public/hero.png rename to examples/typescript/legacy/fullstack/farcaster-miniapp/public/hero.png diff --git a/examples/typescript/fullstack/farcaster-miniapp/public/icon.png b/examples/typescript/legacy/fullstack/farcaster-miniapp/public/icon.png similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/public/icon.png rename to examples/typescript/legacy/fullstack/farcaster-miniapp/public/icon.png diff --git a/examples/typescript/fullstack/farcaster-miniapp/public/logo.png b/examples/typescript/legacy/fullstack/farcaster-miniapp/public/logo.png similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/public/logo.png rename to examples/typescript/legacy/fullstack/farcaster-miniapp/public/logo.png diff --git a/examples/typescript/fullstack/farcaster-miniapp/public/screenshot.png b/examples/typescript/legacy/fullstack/farcaster-miniapp/public/screenshot.png similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/public/screenshot.png rename to examples/typescript/legacy/fullstack/farcaster-miniapp/public/screenshot.png diff --git a/examples/typescript/fullstack/farcaster-miniapp/public/splash.png b/examples/typescript/legacy/fullstack/farcaster-miniapp/public/splash.png similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/public/splash.png rename to examples/typescript/legacy/fullstack/farcaster-miniapp/public/splash.png diff --git a/examples/typescript/fullstack/farcaster-miniapp/tailwind.config.ts b/examples/typescript/legacy/fullstack/farcaster-miniapp/tailwind.config.ts similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/tailwind.config.ts rename to examples/typescript/legacy/fullstack/farcaster-miniapp/tailwind.config.ts diff --git a/examples/typescript/fullstack/farcaster-miniapp/tsconfig.json b/examples/typescript/legacy/fullstack/farcaster-miniapp/tsconfig.json similarity index 100% rename from examples/typescript/fullstack/farcaster-miniapp/tsconfig.json rename to examples/typescript/legacy/fullstack/farcaster-miniapp/tsconfig.json diff --git a/examples/typescript/fullstack/mainnet/.env-local b/examples/typescript/legacy/fullstack/mainnet/.env-local similarity index 100% rename from examples/typescript/fullstack/mainnet/.env-local rename to examples/typescript/legacy/fullstack/mainnet/.env-local diff --git a/examples/typescript/fullstack/mainnet/.gitignore b/examples/typescript/legacy/fullstack/mainnet/.gitignore similarity index 100% rename from examples/typescript/fullstack/mainnet/.gitignore rename to examples/typescript/legacy/fullstack/mainnet/.gitignore diff --git a/examples/typescript/mcp-embedded-wallet/.prettierignore b/examples/typescript/legacy/fullstack/mainnet/.prettierignore similarity index 100% rename from examples/typescript/mcp-embedded-wallet/.prettierignore rename to examples/typescript/legacy/fullstack/mainnet/.prettierignore diff --git a/examples/typescript/mcp-embedded-wallet/.prettierrc b/examples/typescript/legacy/fullstack/mainnet/.prettierrc similarity index 100% rename from examples/typescript/mcp-embedded-wallet/.prettierrc rename to examples/typescript/legacy/fullstack/mainnet/.prettierrc diff --git a/examples/typescript/fullstack/mainnet/README.md b/examples/typescript/legacy/fullstack/mainnet/README.md similarity index 100% rename from examples/typescript/fullstack/mainnet/README.md rename to examples/typescript/legacy/fullstack/mainnet/README.md diff --git a/examples/typescript/fullstack/mainnet/app/api/x402/session-token/route.ts b/examples/typescript/legacy/fullstack/mainnet/app/api/x402/session-token/route.ts similarity index 100% rename from examples/typescript/fullstack/mainnet/app/api/x402/session-token/route.ts rename to examples/typescript/legacy/fullstack/mainnet/app/api/x402/session-token/route.ts diff --git a/examples/typescript/fullstack/mainnet/app/assets/x402_wordmark_dark.png b/examples/typescript/legacy/fullstack/mainnet/app/assets/x402_wordmark_dark.png similarity index 100% rename from examples/typescript/fullstack/mainnet/app/assets/x402_wordmark_dark.png rename to examples/typescript/legacy/fullstack/mainnet/app/assets/x402_wordmark_dark.png diff --git a/examples/typescript/fullstack/mainnet/app/assets/x402_wordmark_dark.svg b/examples/typescript/legacy/fullstack/mainnet/app/assets/x402_wordmark_dark.svg similarity index 100% rename from examples/typescript/fullstack/mainnet/app/assets/x402_wordmark_dark.svg rename to examples/typescript/legacy/fullstack/mainnet/app/assets/x402_wordmark_dark.svg diff --git a/examples/typescript/fullstack/mainnet/app/assets/x402_wordmark_light.svg b/examples/typescript/legacy/fullstack/mainnet/app/assets/x402_wordmark_light.svg similarity index 100% rename from examples/typescript/fullstack/mainnet/app/assets/x402_wordmark_light.svg rename to examples/typescript/legacy/fullstack/mainnet/app/assets/x402_wordmark_light.svg diff --git a/examples/typescript/fullstack/mainnet/app/favicon.ico b/examples/typescript/legacy/fullstack/mainnet/app/favicon.ico similarity index 100% rename from examples/typescript/fullstack/mainnet/app/favicon.ico rename to examples/typescript/legacy/fullstack/mainnet/app/favicon.ico diff --git a/examples/typescript/fullstack/mainnet/app/globals.css b/examples/typescript/legacy/fullstack/mainnet/app/globals.css similarity index 100% rename from examples/typescript/fullstack/mainnet/app/globals.css rename to examples/typescript/legacy/fullstack/mainnet/app/globals.css diff --git a/examples/typescript/fullstack/mainnet/app/layout.tsx b/examples/typescript/legacy/fullstack/mainnet/app/layout.tsx similarity index 100% rename from examples/typescript/fullstack/mainnet/app/layout.tsx rename to examples/typescript/legacy/fullstack/mainnet/app/layout.tsx diff --git a/examples/typescript/fullstack/mainnet/app/page.tsx b/examples/typescript/legacy/fullstack/mainnet/app/page.tsx similarity index 100% rename from examples/typescript/fullstack/mainnet/app/page.tsx rename to examples/typescript/legacy/fullstack/mainnet/app/page.tsx diff --git a/examples/typescript/fullstack/mainnet/app/protected/page.tsx b/examples/typescript/legacy/fullstack/mainnet/app/protected/page.tsx similarity index 100% rename from examples/typescript/fullstack/mainnet/app/protected/page.tsx rename to examples/typescript/legacy/fullstack/mainnet/app/protected/page.tsx diff --git a/examples/typescript/fullstack/mainnet/eslint.config.js b/examples/typescript/legacy/fullstack/mainnet/eslint.config.js similarity index 100% rename from examples/typescript/fullstack/mainnet/eslint.config.js rename to examples/typescript/legacy/fullstack/mainnet/eslint.config.js diff --git a/examples/typescript/fullstack/mainnet/middleware.ts b/examples/typescript/legacy/fullstack/mainnet/middleware.ts similarity index 100% rename from examples/typescript/fullstack/mainnet/middleware.ts rename to examples/typescript/legacy/fullstack/mainnet/middleware.ts diff --git a/examples/typescript/fullstack/mainnet/next.config.ts b/examples/typescript/legacy/fullstack/mainnet/next.config.ts similarity index 100% rename from examples/typescript/fullstack/mainnet/next.config.ts rename to examples/typescript/legacy/fullstack/mainnet/next.config.ts diff --git a/examples/typescript/fullstack/mainnet/package.json b/examples/typescript/legacy/fullstack/mainnet/package.json similarity index 100% rename from examples/typescript/fullstack/mainnet/package.json rename to examples/typescript/legacy/fullstack/mainnet/package.json diff --git a/examples/typescript/fullstack/mainnet/postcss.config.mjs b/examples/typescript/legacy/fullstack/mainnet/postcss.config.mjs similarity index 100% rename from examples/typescript/fullstack/mainnet/postcss.config.mjs rename to examples/typescript/legacy/fullstack/mainnet/postcss.config.mjs diff --git a/examples/typescript/fullstack/mainnet/public/apple-touch-icon.png b/examples/typescript/legacy/fullstack/mainnet/public/apple-touch-icon.png similarity index 100% rename from examples/typescript/fullstack/mainnet/public/apple-touch-icon.png rename to examples/typescript/legacy/fullstack/mainnet/public/apple-touch-icon.png diff --git a/examples/typescript/fullstack/mainnet/public/favicon-96x96.png b/examples/typescript/legacy/fullstack/mainnet/public/favicon-96x96.png similarity index 100% rename from examples/typescript/fullstack/mainnet/public/favicon-96x96.png rename to examples/typescript/legacy/fullstack/mainnet/public/favicon-96x96.png diff --git a/examples/typescript/fullstack/mainnet/public/favicon.svg b/examples/typescript/legacy/fullstack/mainnet/public/favicon.svg similarity index 100% rename from examples/typescript/fullstack/mainnet/public/favicon.svg rename to examples/typescript/legacy/fullstack/mainnet/public/favicon.svg diff --git a/examples/typescript/fullstack/mainnet/public/site.webmanifest b/examples/typescript/legacy/fullstack/mainnet/public/site.webmanifest similarity index 100% rename from examples/typescript/fullstack/mainnet/public/site.webmanifest rename to examples/typescript/legacy/fullstack/mainnet/public/site.webmanifest diff --git a/examples/typescript/fullstack/mainnet/public/web-app-manifest-192x192.png b/examples/typescript/legacy/fullstack/mainnet/public/web-app-manifest-192x192.png similarity index 100% rename from examples/typescript/fullstack/mainnet/public/web-app-manifest-192x192.png rename to examples/typescript/legacy/fullstack/mainnet/public/web-app-manifest-192x192.png diff --git a/examples/typescript/fullstack/mainnet/public/web-app-manifest-512x512.png b/examples/typescript/legacy/fullstack/mainnet/public/web-app-manifest-512x512.png similarity index 100% rename from examples/typescript/fullstack/mainnet/public/web-app-manifest-512x512.png rename to examples/typescript/legacy/fullstack/mainnet/public/web-app-manifest-512x512.png diff --git a/examples/typescript/fullstack/mainnet/public/x402-icon-blue.png b/examples/typescript/legacy/fullstack/mainnet/public/x402-icon-blue.png similarity index 100% rename from examples/typescript/fullstack/mainnet/public/x402-icon-blue.png rename to examples/typescript/legacy/fullstack/mainnet/public/x402-icon-blue.png diff --git a/examples/typescript/fullstack/mainnet/tailwind.config.ts b/examples/typescript/legacy/fullstack/mainnet/tailwind.config.ts similarity index 100% rename from examples/typescript/fullstack/mainnet/tailwind.config.ts rename to examples/typescript/legacy/fullstack/mainnet/tailwind.config.ts diff --git a/e2e/servers/next/tsconfig.json b/examples/typescript/legacy/fullstack/mainnet/tsconfig.json similarity index 100% rename from e2e/servers/next/tsconfig.json rename to examples/typescript/legacy/fullstack/mainnet/tsconfig.json diff --git a/examples/typescript/fullstack/mainnet/types/svg.d.ts b/examples/typescript/legacy/fullstack/mainnet/types/svg.d.ts similarity index 100% rename from examples/typescript/fullstack/mainnet/types/svg.d.ts rename to examples/typescript/legacy/fullstack/mainnet/types/svg.d.ts diff --git a/examples/typescript/fullstack/next-advanced/.eslintrc.json b/examples/typescript/legacy/fullstack/next-advanced/.eslintrc.json similarity index 100% rename from examples/typescript/fullstack/next-advanced/.eslintrc.json rename to examples/typescript/legacy/fullstack/next-advanced/.eslintrc.json diff --git a/examples/typescript/fullstack/next-advanced/.gitignore b/examples/typescript/legacy/fullstack/next-advanced/.gitignore similarity index 100% rename from examples/typescript/fullstack/next-advanced/.gitignore rename to examples/typescript/legacy/fullstack/next-advanced/.gitignore diff --git a/examples/typescript/fullstack/next-advanced/.yarnrc.yml b/examples/typescript/legacy/fullstack/next-advanced/.yarnrc.yml similarity index 100% rename from examples/typescript/fullstack/next-advanced/.yarnrc.yml rename to examples/typescript/legacy/fullstack/next-advanced/.yarnrc.yml diff --git a/examples/typescript/fullstack/next-advanced/README.md b/examples/typescript/legacy/fullstack/next-advanced/README.md similarity index 100% rename from examples/typescript/fullstack/next-advanced/README.md rename to examples/typescript/legacy/fullstack/next-advanced/README.md diff --git a/examples/typescript/fullstack/next-advanced/app/actions.ts b/examples/typescript/legacy/fullstack/next-advanced/app/actions.ts similarity index 100% rename from examples/typescript/fullstack/next-advanced/app/actions.ts rename to examples/typescript/legacy/fullstack/next-advanced/app/actions.ts diff --git a/examples/typescript/fullstack/next-advanced/app/globals.css b/examples/typescript/legacy/fullstack/next-advanced/app/globals.css similarity index 100% rename from examples/typescript/fullstack/next-advanced/app/globals.css rename to examples/typescript/legacy/fullstack/next-advanced/app/globals.css diff --git a/examples/typescript/fullstack/next-advanced/app/layout.tsx b/examples/typescript/legacy/fullstack/next-advanced/app/layout.tsx similarity index 100% rename from examples/typescript/fullstack/next-advanced/app/layout.tsx rename to examples/typescript/legacy/fullstack/next-advanced/app/layout.tsx diff --git a/examples/typescript/fullstack/next-advanced/app/page.tsx b/examples/typescript/legacy/fullstack/next-advanced/app/page.tsx similarity index 100% rename from examples/typescript/fullstack/next-advanced/app/page.tsx rename to examples/typescript/legacy/fullstack/next-advanced/app/page.tsx diff --git a/examples/typescript/fullstack/next-advanced/app/paywall/page.tsx b/examples/typescript/legacy/fullstack/next-advanced/app/paywall/page.tsx similarity index 100% rename from examples/typescript/fullstack/next-advanced/app/paywall/page.tsx rename to examples/typescript/legacy/fullstack/next-advanced/app/paywall/page.tsx diff --git a/examples/typescript/fullstack/next-advanced/app/protected/page.tsx b/examples/typescript/legacy/fullstack/next-advanced/app/protected/page.tsx similarity index 100% rename from examples/typescript/fullstack/next-advanced/app/protected/page.tsx rename to examples/typescript/legacy/fullstack/next-advanced/app/protected/page.tsx diff --git a/examples/typescript/fullstack/next-advanced/app/providers.tsx b/examples/typescript/legacy/fullstack/next-advanced/app/providers.tsx similarity index 100% rename from examples/typescript/fullstack/next-advanced/app/providers.tsx rename to examples/typescript/legacy/fullstack/next-advanced/app/providers.tsx diff --git a/examples/typescript/fullstack/next-advanced/app/svg/ArrowSvg.tsx b/examples/typescript/legacy/fullstack/next-advanced/app/svg/ArrowSvg.tsx similarity index 100% rename from examples/typescript/fullstack/next-advanced/app/svg/ArrowSvg.tsx rename to examples/typescript/legacy/fullstack/next-advanced/app/svg/ArrowSvg.tsx diff --git a/examples/typescript/fullstack/next-advanced/app/svg/Image.tsx b/examples/typescript/legacy/fullstack/next-advanced/app/svg/Image.tsx similarity index 100% rename from examples/typescript/fullstack/next-advanced/app/svg/Image.tsx rename to examples/typescript/legacy/fullstack/next-advanced/app/svg/Image.tsx diff --git a/examples/typescript/fullstack/next-advanced/app/svg/OnchainKit.tsx b/examples/typescript/legacy/fullstack/next-advanced/app/svg/OnchainKit.tsx similarity index 100% rename from examples/typescript/fullstack/next-advanced/app/svg/OnchainKit.tsx rename to examples/typescript/legacy/fullstack/next-advanced/app/svg/OnchainKit.tsx diff --git a/examples/typescript/fullstack/next-advanced/middleware.ts b/examples/typescript/legacy/fullstack/next-advanced/middleware.ts similarity index 100% rename from examples/typescript/fullstack/next-advanced/middleware.ts rename to examples/typescript/legacy/fullstack/next-advanced/middleware.ts diff --git a/examples/typescript/fullstack/next-advanced/next.config.mjs b/examples/typescript/legacy/fullstack/next-advanced/next.config.mjs similarity index 100% rename from examples/typescript/fullstack/next-advanced/next.config.mjs rename to examples/typescript/legacy/fullstack/next-advanced/next.config.mjs diff --git a/examples/typescript/fullstack/next-advanced/package.json b/examples/typescript/legacy/fullstack/next-advanced/package.json similarity index 100% rename from examples/typescript/fullstack/next-advanced/package.json rename to examples/typescript/legacy/fullstack/next-advanced/package.json diff --git a/examples/typescript/fullstack/next-advanced/postcss.config.mjs b/examples/typescript/legacy/fullstack/next-advanced/postcss.config.mjs similarity index 100% rename from examples/typescript/fullstack/next-advanced/postcss.config.mjs rename to examples/typescript/legacy/fullstack/next-advanced/postcss.config.mjs diff --git a/examples/typescript/fullstack/next-advanced/tailwind.config.ts b/examples/typescript/legacy/fullstack/next-advanced/tailwind.config.ts similarity index 100% rename from examples/typescript/fullstack/next-advanced/tailwind.config.ts rename to examples/typescript/legacy/fullstack/next-advanced/tailwind.config.ts diff --git a/examples/typescript/fullstack/next-advanced/tsconfig.json b/examples/typescript/legacy/fullstack/next-advanced/tsconfig.json similarity index 100% rename from examples/typescript/fullstack/next-advanced/tsconfig.json rename to examples/typescript/legacy/fullstack/next-advanced/tsconfig.json diff --git a/examples/typescript/fullstack/next/.env-local b/examples/typescript/legacy/fullstack/next/.env-local similarity index 100% rename from examples/typescript/fullstack/next/.env-local rename to examples/typescript/legacy/fullstack/next/.env-local diff --git a/examples/typescript/fullstack/next/.gitignore b/examples/typescript/legacy/fullstack/next/.gitignore similarity index 100% rename from examples/typescript/fullstack/next/.gitignore rename to examples/typescript/legacy/fullstack/next/.gitignore diff --git a/examples/typescript/mcp/.prettierignore b/examples/typescript/legacy/fullstack/next/.prettierignore similarity index 100% rename from examples/typescript/mcp/.prettierignore rename to examples/typescript/legacy/fullstack/next/.prettierignore diff --git a/examples/typescript/mcp/.prettierrc b/examples/typescript/legacy/fullstack/next/.prettierrc similarity index 100% rename from examples/typescript/mcp/.prettierrc rename to examples/typescript/legacy/fullstack/next/.prettierrc diff --git a/examples/typescript/fullstack/next/README.md b/examples/typescript/legacy/fullstack/next/README.md similarity index 100% rename from examples/typescript/fullstack/next/README.md rename to examples/typescript/legacy/fullstack/next/README.md diff --git a/examples/typescript/fullstack/next/app/assets/x402_wordmark_dark.png b/examples/typescript/legacy/fullstack/next/app/assets/x402_wordmark_dark.png similarity index 100% rename from examples/typescript/fullstack/next/app/assets/x402_wordmark_dark.png rename to examples/typescript/legacy/fullstack/next/app/assets/x402_wordmark_dark.png diff --git a/examples/typescript/fullstack/next/app/assets/x402_wordmark_dark.svg b/examples/typescript/legacy/fullstack/next/app/assets/x402_wordmark_dark.svg similarity index 100% rename from examples/typescript/fullstack/next/app/assets/x402_wordmark_dark.svg rename to examples/typescript/legacy/fullstack/next/app/assets/x402_wordmark_dark.svg diff --git a/examples/typescript/fullstack/next/app/assets/x402_wordmark_light.svg b/examples/typescript/legacy/fullstack/next/app/assets/x402_wordmark_light.svg similarity index 100% rename from examples/typescript/fullstack/next/app/assets/x402_wordmark_light.svg rename to examples/typescript/legacy/fullstack/next/app/assets/x402_wordmark_light.svg diff --git a/examples/typescript/fullstack/next/app/favicon.ico b/examples/typescript/legacy/fullstack/next/app/favicon.ico similarity index 100% rename from examples/typescript/fullstack/next/app/favicon.ico rename to examples/typescript/legacy/fullstack/next/app/favicon.ico diff --git a/examples/typescript/fullstack/next/app/globals.css b/examples/typescript/legacy/fullstack/next/app/globals.css similarity index 100% rename from examples/typescript/fullstack/next/app/globals.css rename to examples/typescript/legacy/fullstack/next/app/globals.css diff --git a/examples/typescript/fullstack/next/app/layout.tsx b/examples/typescript/legacy/fullstack/next/app/layout.tsx similarity index 100% rename from examples/typescript/fullstack/next/app/layout.tsx rename to examples/typescript/legacy/fullstack/next/app/layout.tsx diff --git a/examples/typescript/fullstack/next/app/page.tsx b/examples/typescript/legacy/fullstack/next/app/page.tsx similarity index 100% rename from examples/typescript/fullstack/next/app/page.tsx rename to examples/typescript/legacy/fullstack/next/app/page.tsx diff --git a/examples/typescript/fullstack/next/app/protected/page.tsx b/examples/typescript/legacy/fullstack/next/app/protected/page.tsx similarity index 100% rename from examples/typescript/fullstack/next/app/protected/page.tsx rename to examples/typescript/legacy/fullstack/next/app/protected/page.tsx diff --git a/examples/typescript/fullstack/next/eslint.config.js b/examples/typescript/legacy/fullstack/next/eslint.config.js similarity index 100% rename from examples/typescript/fullstack/next/eslint.config.js rename to examples/typescript/legacy/fullstack/next/eslint.config.js diff --git a/examples/typescript/fullstack/next/middleware.ts b/examples/typescript/legacy/fullstack/next/middleware.ts similarity index 100% rename from examples/typescript/fullstack/next/middleware.ts rename to examples/typescript/legacy/fullstack/next/middleware.ts diff --git a/examples/typescript/fullstack/next/next.config.ts b/examples/typescript/legacy/fullstack/next/next.config.ts similarity index 100% rename from examples/typescript/fullstack/next/next.config.ts rename to examples/typescript/legacy/fullstack/next/next.config.ts diff --git a/examples/typescript/fullstack/next/package-lock.json b/examples/typescript/legacy/fullstack/next/package-lock.json similarity index 100% rename from examples/typescript/fullstack/next/package-lock.json rename to examples/typescript/legacy/fullstack/next/package-lock.json diff --git a/examples/typescript/fullstack/next/package.json b/examples/typescript/legacy/fullstack/next/package.json similarity index 100% rename from examples/typescript/fullstack/next/package.json rename to examples/typescript/legacy/fullstack/next/package.json diff --git a/examples/typescript/fullstack/next/postcss.config.mjs b/examples/typescript/legacy/fullstack/next/postcss.config.mjs similarity index 100% rename from examples/typescript/fullstack/next/postcss.config.mjs rename to examples/typescript/legacy/fullstack/next/postcss.config.mjs diff --git a/examples/typescript/fullstack/next/public/apple-touch-icon.png b/examples/typescript/legacy/fullstack/next/public/apple-touch-icon.png similarity index 100% rename from examples/typescript/fullstack/next/public/apple-touch-icon.png rename to examples/typescript/legacy/fullstack/next/public/apple-touch-icon.png diff --git a/examples/typescript/fullstack/next/public/favicon-96x96.png b/examples/typescript/legacy/fullstack/next/public/favicon-96x96.png similarity index 100% rename from examples/typescript/fullstack/next/public/favicon-96x96.png rename to examples/typescript/legacy/fullstack/next/public/favicon-96x96.png diff --git a/examples/typescript/fullstack/next/public/favicon.svg b/examples/typescript/legacy/fullstack/next/public/favicon.svg similarity index 100% rename from examples/typescript/fullstack/next/public/favicon.svg rename to examples/typescript/legacy/fullstack/next/public/favicon.svg diff --git a/examples/typescript/fullstack/next/public/site.webmanifest b/examples/typescript/legacy/fullstack/next/public/site.webmanifest similarity index 100% rename from examples/typescript/fullstack/next/public/site.webmanifest rename to examples/typescript/legacy/fullstack/next/public/site.webmanifest diff --git a/examples/typescript/fullstack/next/public/web-app-manifest-192x192.png b/examples/typescript/legacy/fullstack/next/public/web-app-manifest-192x192.png similarity index 100% rename from examples/typescript/fullstack/next/public/web-app-manifest-192x192.png rename to examples/typescript/legacy/fullstack/next/public/web-app-manifest-192x192.png diff --git a/examples/typescript/fullstack/next/public/web-app-manifest-512x512.png b/examples/typescript/legacy/fullstack/next/public/web-app-manifest-512x512.png similarity index 100% rename from examples/typescript/fullstack/next/public/web-app-manifest-512x512.png rename to examples/typescript/legacy/fullstack/next/public/web-app-manifest-512x512.png diff --git a/examples/typescript/fullstack/next/public/x402-icon-blue.png b/examples/typescript/legacy/fullstack/next/public/x402-icon-blue.png similarity index 100% rename from examples/typescript/fullstack/next/public/x402-icon-blue.png rename to examples/typescript/legacy/fullstack/next/public/x402-icon-blue.png diff --git a/examples/typescript/fullstack/next/tailwind.config.ts b/examples/typescript/legacy/fullstack/next/tailwind.config.ts similarity index 100% rename from examples/typescript/fullstack/next/tailwind.config.ts rename to examples/typescript/legacy/fullstack/next/tailwind.config.ts diff --git a/examples/typescript/fullstack/mainnet/tsconfig.json b/examples/typescript/legacy/fullstack/next/tsconfig.json similarity index 100% rename from examples/typescript/fullstack/mainnet/tsconfig.json rename to examples/typescript/legacy/fullstack/next/tsconfig.json diff --git a/examples/typescript/fullstack/next/types/svg.d.ts b/examples/typescript/legacy/fullstack/next/types/svg.d.ts similarity index 100% rename from examples/typescript/fullstack/next/types/svg.d.ts rename to examples/typescript/legacy/fullstack/next/types/svg.d.ts diff --git a/examples/typescript/mcp-embedded-wallet/.env.example b/examples/typescript/legacy/mcp-embedded-wallet/.env.example similarity index 100% rename from examples/typescript/mcp-embedded-wallet/.env.example rename to examples/typescript/legacy/mcp-embedded-wallet/.env.example diff --git a/examples/typescript/mcp-embedded-wallet/.gitignore b/examples/typescript/legacy/mcp-embedded-wallet/.gitignore similarity index 100% rename from examples/typescript/mcp-embedded-wallet/.gitignore rename to examples/typescript/legacy/mcp-embedded-wallet/.gitignore diff --git a/examples/typescript/servers/advanced/.prettierignore b/examples/typescript/legacy/mcp-embedded-wallet/.prettierignore similarity index 100% rename from examples/typescript/servers/advanced/.prettierignore rename to examples/typescript/legacy/mcp-embedded-wallet/.prettierignore diff --git a/examples/typescript/servers/advanced/.prettierrc b/examples/typescript/legacy/mcp-embedded-wallet/.prettierrc similarity index 100% rename from examples/typescript/servers/advanced/.prettierrc rename to examples/typescript/legacy/mcp-embedded-wallet/.prettierrc diff --git a/examples/typescript/mcp-embedded-wallet/README.md b/examples/typescript/legacy/mcp-embedded-wallet/README.md similarity index 100% rename from examples/typescript/mcp-embedded-wallet/README.md rename to examples/typescript/legacy/mcp-embedded-wallet/README.md diff --git a/examples/typescript/mcp-embedded-wallet/TODO.md b/examples/typescript/legacy/mcp-embedded-wallet/TODO.md similarity index 100% rename from examples/typescript/mcp-embedded-wallet/TODO.md rename to examples/typescript/legacy/mcp-embedded-wallet/TODO.md diff --git a/examples/typescript/mcp-embedded-wallet/electron.ts b/examples/typescript/legacy/mcp-embedded-wallet/electron.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/electron.ts rename to examples/typescript/legacy/mcp-embedded-wallet/electron.ts diff --git a/examples/typescript/mcp-embedded-wallet/eslint.config.js b/examples/typescript/legacy/mcp-embedded-wallet/eslint.config.js similarity index 100% rename from examples/typescript/mcp-embedded-wallet/eslint.config.js rename to examples/typescript/legacy/mcp-embedded-wallet/eslint.config.js diff --git a/examples/typescript/mcp-embedded-wallet/index.html b/examples/typescript/legacy/mcp-embedded-wallet/index.html similarity index 100% rename from examples/typescript/mcp-embedded-wallet/index.html rename to examples/typescript/legacy/mcp-embedded-wallet/index.html diff --git a/examples/typescript/mcp-embedded-wallet/index.ts b/examples/typescript/legacy/mcp-embedded-wallet/index.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/index.ts rename to examples/typescript/legacy/mcp-embedded-wallet/index.ts diff --git a/examples/typescript/mcp-embedded-wallet/logger.ts b/examples/typescript/legacy/mcp-embedded-wallet/logger.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/logger.ts rename to examples/typescript/legacy/mcp-embedded-wallet/logger.ts diff --git a/examples/typescript/mcp-embedded-wallet/mcp.ts b/examples/typescript/legacy/mcp-embedded-wallet/mcp.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/mcp.ts rename to examples/typescript/legacy/mcp-embedded-wallet/mcp.ts diff --git a/examples/typescript/mcp-embedded-wallet/package.json b/examples/typescript/legacy/mcp-embedded-wallet/package.json similarity index 100% rename from examples/typescript/mcp-embedded-wallet/package.json rename to examples/typescript/legacy/mcp-embedded-wallet/package.json diff --git a/examples/typescript/mcp-embedded-wallet/pnpm-lock.yaml b/examples/typescript/legacy/mcp-embedded-wallet/pnpm-lock.yaml similarity index 100% rename from examples/typescript/mcp-embedded-wallet/pnpm-lock.yaml rename to examples/typescript/legacy/mcp-embedded-wallet/pnpm-lock.yaml diff --git a/examples/typescript/mcp-embedded-wallet/preload.js b/examples/typescript/legacy/mcp-embedded-wallet/preload.js similarity index 100% rename from examples/typescript/mcp-embedded-wallet/preload.js rename to examples/typescript/legacy/mcp-embedded-wallet/preload.js diff --git a/examples/typescript/mcp-embedded-wallet/src/.eslintrc.json b/examples/typescript/legacy/mcp-embedded-wallet/src/.eslintrc.json similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/.eslintrc.json rename to examples/typescript/legacy/mcp-embedded-wallet/src/.eslintrc.json diff --git a/examples/typescript/mcp-embedded-wallet/src/.prettierrc b/examples/typescript/legacy/mcp-embedded-wallet/src/.prettierrc similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/.prettierrc rename to examples/typescript/legacy/mcp-embedded-wallet/src/.prettierrc diff --git a/examples/typescript/mcp-embedded-wallet/src/App.tsx b/examples/typescript/legacy/mcp-embedded-wallet/src/App.tsx similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/App.tsx rename to examples/typescript/legacy/mcp-embedded-wallet/src/App.tsx diff --git a/examples/typescript/mcp-embedded-wallet/src/ChainProvider.tsx b/examples/typescript/legacy/mcp-embedded-wallet/src/ChainProvider.tsx similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/ChainProvider.tsx rename to examples/typescript/legacy/mcp-embedded-wallet/src/ChainProvider.tsx diff --git a/examples/typescript/mcp-embedded-wallet/src/cdpConfig.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/cdpConfig.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/cdpConfig.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/cdpConfig.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/components/BudgetModal/BudgetModal.tsx b/examples/typescript/legacy/mcp-embedded-wallet/src/components/BudgetModal/BudgetModal.tsx similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/BudgetModal/BudgetModal.tsx rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/BudgetModal/BudgetModal.tsx diff --git a/examples/typescript/mcp-embedded-wallet/src/components/BudgetModal/index.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/components/BudgetModal/index.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/BudgetModal/index.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/BudgetModal/index.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/components/Button/Button.tsx b/examples/typescript/legacy/mcp-embedded-wallet/src/components/Button/Button.tsx similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/Button/Button.tsx rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/Button/Button.tsx diff --git a/examples/typescript/mcp-embedded-wallet/src/components/Button/index.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/components/Button/index.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/Button/index.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/Button/index.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/components/DiscoveryModal/DiscoveryModal.module.css b/examples/typescript/legacy/mcp-embedded-wallet/src/components/DiscoveryModal/DiscoveryModal.module.css similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/DiscoveryModal/DiscoveryModal.module.css rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/DiscoveryModal/DiscoveryModal.module.css diff --git a/examples/typescript/mcp-embedded-wallet/src/components/DiscoveryModal/DiscoveryModal.tsx b/examples/typescript/legacy/mcp-embedded-wallet/src/components/DiscoveryModal/DiscoveryModal.tsx similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/DiscoveryModal/DiscoveryModal.tsx rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/DiscoveryModal/DiscoveryModal.tsx diff --git a/examples/typescript/mcp-embedded-wallet/src/components/DiscoveryModal/index.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/components/DiscoveryModal/index.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/DiscoveryModal/index.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/DiscoveryModal/index.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/components/GroupedOperation/GroupedOperation.tsx b/examples/typescript/legacy/mcp-embedded-wallet/src/components/GroupedOperation/GroupedOperation.tsx similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/GroupedOperation/GroupedOperation.tsx rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/GroupedOperation/GroupedOperation.tsx diff --git a/examples/typescript/mcp-embedded-wallet/src/components/GroupedOperation/index.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/components/GroupedOperation/index.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/GroupedOperation/index.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/GroupedOperation/index.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/components/Header/Header.module.css b/examples/typescript/legacy/mcp-embedded-wallet/src/components/Header/Header.module.css similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/Header/Header.module.css rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/Header/Header.module.css diff --git a/examples/typescript/mcp-embedded-wallet/src/components/Header/Header.tsx b/examples/typescript/legacy/mcp-embedded-wallet/src/components/Header/Header.tsx similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/Header/Header.tsx rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/Header/Header.tsx diff --git a/examples/typescript/mcp-embedded-wallet/src/components/Header/TestX402Button.tsx b/examples/typescript/legacy/mcp-embedded-wallet/src/components/Header/TestX402Button.tsx similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/Header/TestX402Button.tsx rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/Header/TestX402Button.tsx diff --git a/examples/typescript/mcp-embedded-wallet/src/components/Header/index.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/components/Header/index.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/Header/index.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/Header/index.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/components/OperationBadge/OperationBadge.module.css b/examples/typescript/legacy/mcp-embedded-wallet/src/components/OperationBadge/OperationBadge.module.css similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/OperationBadge/OperationBadge.module.css rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/OperationBadge/OperationBadge.module.css diff --git a/examples/typescript/mcp-embedded-wallet/src/components/OperationBadge/OperationBadge.tsx b/examples/typescript/legacy/mcp-embedded-wallet/src/components/OperationBadge/OperationBadge.tsx similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/OperationBadge/OperationBadge.tsx rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/OperationBadge/OperationBadge.tsx diff --git a/examples/typescript/mcp-embedded-wallet/src/components/OperationBadge/index.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/components/OperationBadge/index.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/OperationBadge/index.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/OperationBadge/index.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/components/OperationDetails/HttpOperationDetails.tsx b/examples/typescript/legacy/mcp-embedded-wallet/src/components/OperationDetails/HttpOperationDetails.tsx similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/OperationDetails/HttpOperationDetails.tsx rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/OperationDetails/HttpOperationDetails.tsx diff --git a/examples/typescript/mcp-embedded-wallet/src/components/OperationDetails/WalletOperationDetails.tsx b/examples/typescript/legacy/mcp-embedded-wallet/src/components/OperationDetails/WalletOperationDetails.tsx similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/OperationDetails/WalletOperationDetails.tsx rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/OperationDetails/WalletOperationDetails.tsx diff --git a/examples/typescript/mcp-embedded-wallet/src/components/OperationDetails/index.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/components/OperationDetails/index.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/OperationDetails/index.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/OperationDetails/index.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/components/OperationsList/OperationsList.tsx b/examples/typescript/legacy/mcp-embedded-wallet/src/components/OperationsList/OperationsList.tsx similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/OperationsList/OperationsList.tsx rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/OperationsList/OperationsList.tsx diff --git a/examples/typescript/mcp-embedded-wallet/src/components/OperationsList/index.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/components/OperationsList/index.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/OperationsList/index.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/OperationsList/index.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/components/ReceiveModal/ReceiveModal.tsx b/examples/typescript/legacy/mcp-embedded-wallet/src/components/ReceiveModal/ReceiveModal.tsx similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/ReceiveModal/ReceiveModal.tsx rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/ReceiveModal/ReceiveModal.tsx diff --git a/examples/typescript/mcp-embedded-wallet/src/components/SessionSpendingTracker/SessionSpendingTracker.tsx b/examples/typescript/legacy/mcp-embedded-wallet/src/components/SessionSpendingTracker/SessionSpendingTracker.tsx similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/SessionSpendingTracker/SessionSpendingTracker.tsx rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/SessionSpendingTracker/SessionSpendingTracker.tsx diff --git a/examples/typescript/mcp-embedded-wallet/src/components/SessionSpendingTracker/index.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/components/SessionSpendingTracker/index.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/SessionSpendingTracker/index.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/SessionSpendingTracker/index.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/components/SignIn.tsx b/examples/typescript/legacy/mcp-embedded-wallet/src/components/SignIn.tsx similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/SignIn.tsx rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/SignIn.tsx diff --git a/examples/typescript/mcp-embedded-wallet/src/components/SignOutButton/SignOutButton.module.css b/examples/typescript/legacy/mcp-embedded-wallet/src/components/SignOutButton/SignOutButton.module.css similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/SignOutButton/SignOutButton.module.css rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/SignOutButton/SignOutButton.module.css diff --git a/examples/typescript/mcp-embedded-wallet/src/components/SignOutButton/SignOutButton.tsx b/examples/typescript/legacy/mcp-embedded-wallet/src/components/SignOutButton/SignOutButton.tsx similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/SignOutButton/SignOutButton.tsx rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/SignOutButton/SignOutButton.tsx diff --git a/examples/typescript/mcp-embedded-wallet/src/components/SignOutButton/index.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/components/SignOutButton/index.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/SignOutButton/index.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/SignOutButton/index.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/components/Wallet/Wallet.module.css b/examples/typescript/legacy/mcp-embedded-wallet/src/components/Wallet/Wallet.module.css similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/Wallet/Wallet.module.css rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/Wallet/Wallet.module.css diff --git a/examples/typescript/mcp-embedded-wallet/src/components/Wallet/Wallet.tsx b/examples/typescript/legacy/mcp-embedded-wallet/src/components/Wallet/Wallet.tsx similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/Wallet/Wallet.tsx rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/Wallet/Wallet.tsx diff --git a/examples/typescript/mcp-embedded-wallet/src/components/Wallet/index.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/components/Wallet/index.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/Wallet/index.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/Wallet/index.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/components/WithdrawModal/WithdrawModal.module.css b/examples/typescript/legacy/mcp-embedded-wallet/src/components/WithdrawModal/WithdrawModal.module.css similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/WithdrawModal/WithdrawModal.module.css rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/WithdrawModal/WithdrawModal.module.css diff --git a/examples/typescript/mcp-embedded-wallet/src/components/WithdrawModal/WithdrawModal.tsx b/examples/typescript/legacy/mcp-embedded-wallet/src/components/WithdrawModal/WithdrawModal.tsx similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/WithdrawModal/WithdrawModal.tsx rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/WithdrawModal/WithdrawModal.tsx diff --git a/examples/typescript/mcp-embedded-wallet/src/components/WithdrawModal/index.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/components/WithdrawModal/index.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/components/WithdrawModal/index.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/components/WithdrawModal/index.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/main.module.css b/examples/typescript/legacy/mcp-embedded-wallet/src/main.module.css similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/main.module.css rename to examples/typescript/legacy/mcp-embedded-wallet/src/main.module.css diff --git a/examples/typescript/mcp-embedded-wallet/src/main.tsx b/examples/typescript/legacy/mcp-embedded-wallet/src/main.tsx similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/main.tsx rename to examples/typescript/legacy/mcp-embedded-wallet/src/main.tsx diff --git a/examples/typescript/mcp-embedded-wallet/src/package.json b/examples/typescript/legacy/mcp-embedded-wallet/src/package.json similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/package.json rename to examples/typescript/legacy/mcp-embedded-wallet/src/package.json diff --git a/examples/typescript/mcp-embedded-wallet/src/services/discovery.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/services/discovery.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/services/discovery.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/services/discovery.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/services/walletService.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/services/walletService.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/services/walletService.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/services/walletService.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/services/withdrawalService.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/services/withdrawalService.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/services/withdrawalService.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/services/withdrawalService.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/stores/budget.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/stores/budget.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/stores/budget.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/stores/budget.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/stores/operations.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/stores/operations.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/stores/operations.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/stores/operations.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/stores/x402_flow.md b/examples/typescript/legacy/mcp-embedded-wallet/src/stores/x402_flow.md similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/stores/x402_flow.md rename to examples/typescript/legacy/mcp-embedded-wallet/src/stores/x402_flow.md diff --git a/examples/typescript/mcp-embedded-wallet/src/utils/balanceChecker.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/utils/balanceChecker.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/utils/balanceChecker.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/utils/balanceChecker.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/utils/chainConfig.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/utils/chainConfig.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/utils/chainConfig.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/utils/chainConfig.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/utils/paymentInterceptor.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/utils/paymentInterceptor.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/utils/paymentInterceptor.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/utils/paymentInterceptor.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/utils/x402Client.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/utils/x402Client.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/utils/x402Client.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/utils/x402Client.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/utils/x402ErrorHandler.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/utils/x402ErrorHandler.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/utils/x402ErrorHandler.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/utils/x402ErrorHandler.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/utils/x402Utils.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/utils/x402Utils.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/utils/x402Utils.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/utils/x402Utils.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/vite-env.d.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/vite-env.d.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/vite-env.d.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/vite-env.d.ts diff --git a/examples/typescript/mcp-embedded-wallet/src/window.ts b/examples/typescript/legacy/mcp-embedded-wallet/src/window.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/src/window.ts rename to examples/typescript/legacy/mcp-embedded-wallet/src/window.ts diff --git a/examples/typescript/mcp-embedded-wallet/tsconfig.json b/examples/typescript/legacy/mcp-embedded-wallet/tsconfig.json similarity index 100% rename from examples/typescript/mcp-embedded-wallet/tsconfig.json rename to examples/typescript/legacy/mcp-embedded-wallet/tsconfig.json diff --git a/examples/typescript/mcp-embedded-wallet/vite.config.ts b/examples/typescript/legacy/mcp-embedded-wallet/vite.config.ts similarity index 100% rename from examples/typescript/mcp-embedded-wallet/vite.config.ts rename to examples/typescript/legacy/mcp-embedded-wallet/vite.config.ts diff --git a/examples/typescript/mcp/.env-local b/examples/typescript/legacy/mcp/.env-local similarity index 100% rename from examples/typescript/mcp/.env-local rename to examples/typescript/legacy/mcp/.env-local diff --git a/examples/typescript/servers/express/.prettierignore b/examples/typescript/legacy/mcp/.prettierignore similarity index 100% rename from examples/typescript/servers/express/.prettierignore rename to examples/typescript/legacy/mcp/.prettierignore diff --git a/examples/typescript/servers/express/.prettierrc b/examples/typescript/legacy/mcp/.prettierrc similarity index 100% rename from examples/typescript/servers/express/.prettierrc rename to examples/typescript/legacy/mcp/.prettierrc diff --git a/examples/typescript/mcp/README.md b/examples/typescript/legacy/mcp/README.md similarity index 100% rename from examples/typescript/mcp/README.md rename to examples/typescript/legacy/mcp/README.md diff --git a/examples/typescript/mcp/eslint.config.js b/examples/typescript/legacy/mcp/eslint.config.js similarity index 100% rename from examples/typescript/mcp/eslint.config.js rename to examples/typescript/legacy/mcp/eslint.config.js diff --git a/examples/typescript/mcp/index.ts b/examples/typescript/legacy/mcp/index.ts similarity index 100% rename from examples/typescript/mcp/index.ts rename to examples/typescript/legacy/mcp/index.ts diff --git a/examples/typescript/mcp/package.json b/examples/typescript/legacy/mcp/package.json similarity index 100% rename from examples/typescript/mcp/package.json rename to examples/typescript/legacy/mcp/package.json diff --git a/examples/typescript/mcp/tsconfig.json b/examples/typescript/legacy/mcp/tsconfig.json similarity index 100% rename from examples/typescript/mcp/tsconfig.json rename to examples/typescript/legacy/mcp/tsconfig.json diff --git a/examples/typescript/servers/advanced/.env-local b/examples/typescript/legacy/servers/advanced/.env-local similarity index 100% rename from examples/typescript/servers/advanced/.env-local rename to examples/typescript/legacy/servers/advanced/.env-local diff --git a/examples/typescript/servers/hono/.prettierignore b/examples/typescript/legacy/servers/advanced/.prettierignore similarity index 100% rename from examples/typescript/servers/hono/.prettierignore rename to examples/typescript/legacy/servers/advanced/.prettierignore diff --git a/examples/typescript/servers/hono/.prettierrc b/examples/typescript/legacy/servers/advanced/.prettierrc similarity index 100% rename from examples/typescript/servers/hono/.prettierrc rename to examples/typescript/legacy/servers/advanced/.prettierrc diff --git a/examples/typescript/servers/advanced/README.md b/examples/typescript/legacy/servers/advanced/README.md similarity index 100% rename from examples/typescript/servers/advanced/README.md rename to examples/typescript/legacy/servers/advanced/README.md diff --git a/examples/typescript/servers/express/eslint.config.js b/examples/typescript/legacy/servers/advanced/eslint.config.js similarity index 100% rename from examples/typescript/servers/express/eslint.config.js rename to examples/typescript/legacy/servers/advanced/eslint.config.js diff --git a/examples/typescript/servers/advanced/index.ts b/examples/typescript/legacy/servers/advanced/index.ts similarity index 100% rename from examples/typescript/servers/advanced/index.ts rename to examples/typescript/legacy/servers/advanced/index.ts diff --git a/examples/typescript/servers/advanced/package.json b/examples/typescript/legacy/servers/advanced/package.json similarity index 100% rename from examples/typescript/servers/advanced/package.json rename to examples/typescript/legacy/servers/advanced/package.json diff --git a/examples/typescript/servers/express/tsconfig.json b/examples/typescript/legacy/servers/advanced/tsconfig.json similarity index 100% rename from examples/typescript/servers/express/tsconfig.json rename to examples/typescript/legacy/servers/advanced/tsconfig.json diff --git a/examples/typescript/servers/express/.env-local b/examples/typescript/legacy/servers/express/.env-local similarity index 100% rename from examples/typescript/servers/express/.env-local rename to examples/typescript/legacy/servers/express/.env-local diff --git a/examples/typescript/servers/mainnet/.prettierignore b/examples/typescript/legacy/servers/express/.prettierignore similarity index 100% rename from examples/typescript/servers/mainnet/.prettierignore rename to examples/typescript/legacy/servers/express/.prettierignore diff --git a/examples/typescript/servers/mainnet/.prettierrc b/examples/typescript/legacy/servers/express/.prettierrc similarity index 100% rename from examples/typescript/servers/mainnet/.prettierrc rename to examples/typescript/legacy/servers/express/.prettierrc diff --git a/examples/typescript/legacy/servers/express/README.md b/examples/typescript/legacy/servers/express/README.md new file mode 100644 index 000000000..5adab235c --- /dev/null +++ b/examples/typescript/legacy/servers/express/README.md @@ -0,0 +1,146 @@ +# x402-express Example Server + +This is an example Express.js server that demonstrates how to use the `x402-express` middleware to implement paywall functionality in your API endpoints. + +## Prerequisites + +- Node.js v20+ (install via [nvm](https://github.com/nvm-sh/nvm)) +- pnpm v10 (install via [pnpm.io/installation](https://pnpm.io/installation)) +- A valid Ethereum address for receiving payments +- Coinbase Developer Platform API Key & Secret (if accepting payments on Base mainnet) + -- Get them here [https://portal.cdp.coinbase.com/projects](https://portal.cdp.coinbase.com/projects) + +## Setup + +1. Copy `.env-local` to `.env` and add your Ethereum address to receive payments: + +```bash +cp .env-local .env +``` + +2. Install and build all packages from the typescript examples root: +```bash +cd ../../ +pnpm install +pnpm build +cd servers/express +``` + +3. Run the server +```bash +pnpm install +pnpm dev +``` + +## Testing the Server + +You can test the server using one of the example clients: + +### Using the Fetch Client +```bash +cd ../clients/fetch +# Ensure .env is setup +pnpm install +pnpm dev +``` + +### Using the Axios Client +```bash +cd ../clients/axios +# Ensure .env is setup +pnpm install +pnpm dev +``` + +These clients will demonstrate how to: +1. Make an initial request to get payment requirements +2. Process the payment requirements +3. Make a second request with the payment token + +## Example Endpoint + +The server includes a single example endpoint at `/weather` that requires a payment of $0.001 to access. The endpoint returns a simple weather report. + +## Response Format + +### Payment Required (402) +```json +{ + "error": "X-PAYMENT header is required", + "paymentRequirements": { + "scheme": "exact", + "network": "base", + "maxAmountRequired": "1000", + "resource": "http://localhost:4021/weather", + "description": "", + "mimeType": "", + "payTo": "0xYourAddress", + "maxTimeoutSeconds": 60, + "asset": "0x...", + "outputSchema": null, + "extra": null + } +} +``` + +### Successful Response +```ts +// Body +{ + "report": { + "weather": "sunny", + "temperature": 70 + } +} +// Headers +{ + "X-PAYMENT-RESPONSE": "..." // Encoded response object +} +``` + +## Extending the Example + +To add more paid endpoints, follow this pattern: + +```typescript +// First, configure the payment middleware with your routes +app.use( + paymentMiddleware( + payTo, + { + // Define your routes and their payment requirements + "GET /your-endpoint": { + price: "$0.10", + network: "base-sepolia", + }, + "/premium/*": { + price: { + amount: "100000", + asset: { + address: "0xabc", + decimals: 18, + eip712: { + name: "WETH", + version: "1", + }, + }, + }, + network: "base-sepolia", + }, + }, + ), +); + +// Then define your routes as normal +app.get("/your-endpoint", (req, res) => { + res.json({ + // Your response data + }); +}); + +app.get("/premium/content", (req, res) => { + res.json({ + content: "This is premium content", + }); +}); +``` diff --git a/examples/typescript/servers/hono/eslint.config.js b/examples/typescript/legacy/servers/express/eslint.config.js similarity index 100% rename from examples/typescript/servers/hono/eslint.config.js rename to examples/typescript/legacy/servers/express/eslint.config.js diff --git a/examples/typescript/servers/express/index.ts b/examples/typescript/legacy/servers/express/index.ts similarity index 100% rename from examples/typescript/servers/express/index.ts rename to examples/typescript/legacy/servers/express/index.ts diff --git a/examples/typescript/servers/express/package.json b/examples/typescript/legacy/servers/express/package.json similarity index 100% rename from examples/typescript/servers/express/package.json rename to examples/typescript/legacy/servers/express/package.json diff --git a/examples/typescript/servers/hono/tsconfig.json b/examples/typescript/legacy/servers/express/tsconfig.json similarity index 100% rename from examples/typescript/servers/hono/tsconfig.json rename to examples/typescript/legacy/servers/express/tsconfig.json diff --git a/examples/typescript/servers/hono/.env-local b/examples/typescript/legacy/servers/hono/.env-local similarity index 100% rename from examples/typescript/servers/hono/.env-local rename to examples/typescript/legacy/servers/hono/.env-local diff --git a/typescript/packages/coinbase-x402/.prettierignore b/examples/typescript/legacy/servers/hono/.prettierignore similarity index 100% rename from typescript/packages/coinbase-x402/.prettierignore rename to examples/typescript/legacy/servers/hono/.prettierignore diff --git a/typescript/packages/coinbase-x402/.prettierrc b/examples/typescript/legacy/servers/hono/.prettierrc similarity index 100% rename from typescript/packages/coinbase-x402/.prettierrc rename to examples/typescript/legacy/servers/hono/.prettierrc diff --git a/examples/typescript/servers/hono/README.md b/examples/typescript/legacy/servers/hono/README.md similarity index 100% rename from examples/typescript/servers/hono/README.md rename to examples/typescript/legacy/servers/hono/README.md diff --git a/examples/typescript/servers/mainnet/eslint.config.js b/examples/typescript/legacy/servers/hono/eslint.config.js similarity index 100% rename from examples/typescript/servers/mainnet/eslint.config.js rename to examples/typescript/legacy/servers/hono/eslint.config.js diff --git a/examples/typescript/servers/hono/index.ts b/examples/typescript/legacy/servers/hono/index.ts similarity index 100% rename from examples/typescript/servers/hono/index.ts rename to examples/typescript/legacy/servers/hono/index.ts diff --git a/examples/typescript/servers/hono/package.json b/examples/typescript/legacy/servers/hono/package.json similarity index 100% rename from examples/typescript/servers/hono/package.json rename to examples/typescript/legacy/servers/hono/package.json diff --git a/examples/typescript/servers/mainnet/tsconfig.json b/examples/typescript/legacy/servers/hono/tsconfig.json similarity index 100% rename from examples/typescript/servers/mainnet/tsconfig.json rename to examples/typescript/legacy/servers/hono/tsconfig.json diff --git a/examples/typescript/servers/mainnet/.env-local b/examples/typescript/legacy/servers/mainnet/.env-local similarity index 100% rename from examples/typescript/servers/mainnet/.env-local rename to examples/typescript/legacy/servers/mainnet/.env-local diff --git a/typescript/packages/x402-axios/.prettierignore b/examples/typescript/legacy/servers/mainnet/.prettierignore similarity index 100% rename from typescript/packages/x402-axios/.prettierignore rename to examples/typescript/legacy/servers/mainnet/.prettierignore diff --git a/typescript/packages/x402-axios/.prettierrc b/examples/typescript/legacy/servers/mainnet/.prettierrc similarity index 100% rename from typescript/packages/x402-axios/.prettierrc rename to examples/typescript/legacy/servers/mainnet/.prettierrc diff --git a/examples/typescript/servers/mainnet/README.md b/examples/typescript/legacy/servers/mainnet/README.md similarity index 100% rename from examples/typescript/servers/mainnet/README.md rename to examples/typescript/legacy/servers/mainnet/README.md diff --git a/examples/typescript/legacy/servers/mainnet/eslint.config.js b/examples/typescript/legacy/servers/mainnet/eslint.config.js new file mode 100644 index 000000000..e2fde7b3b --- /dev/null +++ b/examples/typescript/legacy/servers/mainnet/eslint.config.js @@ -0,0 +1,73 @@ +import js from "@eslint/js"; +import ts from "@typescript-eslint/eslint-plugin"; +import tsParser from "@typescript-eslint/parser"; +import prettier from "eslint-plugin-prettier"; +import jsdoc from "eslint-plugin-jsdoc"; +import importPlugin from "eslint-plugin-import"; + +export default [ + { + ignores: ["dist/**", "node_modules/**"], + }, + { + files: ["**/*.ts"], + languageOptions: { + parser: tsParser, + sourceType: "module", + ecmaVersion: 2020, + globals: { + process: "readonly", + __dirname: "readonly", + module: "readonly", + require: "readonly", + Buffer: "readonly", + console: "readonly", + exports: "readonly", + setTimeout: "readonly", + clearTimeout: "readonly", + setInterval: "readonly", + clearInterval: "readonly", + }, + }, + plugins: { + "@typescript-eslint": ts, + prettier: prettier, + jsdoc: jsdoc, + import: importPlugin, + }, + rules: { + ...ts.configs.recommended.rules, + "import/first": "error", + "prettier/prettier": "error", + "@typescript-eslint/member-ordering": "error", + "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_$" }], + "jsdoc/tag-lines": ["error", "any", { startLines: 1 }], + "jsdoc/check-alignment": "error", + "jsdoc/no-undefined-types": "off", + "jsdoc/check-param-names": "error", + "jsdoc/check-tag-names": "error", + "jsdoc/check-types": "error", + "jsdoc/implements-on-classes": "error", + "jsdoc/require-description": "error", + "jsdoc/require-jsdoc": [ + "error", + { + require: { + FunctionDeclaration: true, + MethodDefinition: true, + ClassDeclaration: true, + ArrowFunctionExpression: false, + FunctionExpression: false, + }, + }, + ], + "jsdoc/require-param": "error", + "jsdoc/require-param-description": "error", + "jsdoc/require-param-type": "off", + "jsdoc/require-returns": "error", + "jsdoc/require-returns-description": "error", + "jsdoc/require-returns-type": "off", + "jsdoc/require-hyphen-before-param-description": ["error", "always"], + }, + }, +]; diff --git a/examples/typescript/servers/mainnet/index.ts b/examples/typescript/legacy/servers/mainnet/index.ts similarity index 97% rename from examples/typescript/servers/mainnet/index.ts rename to examples/typescript/legacy/servers/mainnet/index.ts index 4e9c3b87d..9b1546a8a 100644 --- a/examples/typescript/servers/mainnet/index.ts +++ b/examples/typescript/legacy/servers/mainnet/index.ts @@ -23,7 +23,7 @@ app.use( "GET /weather": { // USDC amount in dollars price: "$0.001", - network: "base", + network: "solana", }, }, // Pass the mainnet facilitator to the payment middleware diff --git a/examples/typescript/servers/mainnet/package.json b/examples/typescript/legacy/servers/mainnet/package.json similarity index 100% rename from examples/typescript/servers/mainnet/package.json rename to examples/typescript/legacy/servers/mainnet/package.json diff --git a/examples/typescript/legacy/servers/mainnet/tsconfig.json b/examples/typescript/legacy/servers/mainnet/tsconfig.json new file mode 100644 index 000000000..78f9479b1 --- /dev/null +++ b/examples/typescript/legacy/servers/mainnet/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ES2020", + "moduleResolution": "bundler", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "skipLibCheck": true, + "strict": true, + "resolveJsonModule": true, + "baseUrl": ".", + "types": ["node"] + }, + "include": ["index.ts"] +} diff --git a/examples/typescript/pnpm-lock.yaml b/examples/typescript/pnpm-lock.yaml index 657979832..53d27c94c 100644 --- a/examples/typescript/pnpm-lock.yaml +++ b/examples/typescript/pnpm-lock.yaml @@ -18,7 +18,7 @@ importers: specifier: ^5.8.3 version: 5.9.2 - ../../typescript/packages/coinbase-x402: + ../../typescript/packages/legacy/coinbase-x402: dependencies: '@coinbase/cdp-sdk': specifier: ^1.29.0 @@ -79,7 +79,7 @@ importers: 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) - ../../typescript/packages/x402: + ../../typescript/packages/legacy/x402: dependencies: '@scure/base': specifier: ^1.2.6 @@ -99,6 +99,18 @@ importers: '@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)) + '@solana/wallet-standard-features': + specifier: ^1.3.0 + version: 1.3.0 + '@wallet-standard/app': + specifier: ^1.1.0 + version: 1.1.0 + '@wallet-standard/base': + specifier: ^1.1.0 + version: 1.1.0 + '@wallet-standard/features': + specifier: ^1.1.0 + version: 1.1.0 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) @@ -185,7 +197,7 @@ importers: 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) - ../../typescript/packages/x402-axios: + ../../typescript/packages/legacy/x402-axios: dependencies: axios: specifier: ^1.7.9 @@ -246,7 +258,7 @@ importers: 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) - ../../typescript/packages/x402-express: + ../../typescript/packages/legacy/x402-express: dependencies: '@coinbase/cdp-sdk': specifier: ^1.22.0 @@ -316,7 +328,7 @@ importers: 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) - ../../typescript/packages/x402-fetch: + ../../typescript/packages/legacy/x402-fetch: dependencies: viem: specifier: ^2.21.26 @@ -374,7 +386,7 @@ importers: 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) - ../../typescript/packages/x402-hono: + ../../typescript/packages/legacy/x402-hono: dependencies: '@coinbase/cdp-sdk': specifier: ^1.22.0 @@ -441,7 +453,7 @@ importers: 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) - ../../typescript/packages/x402-next: + ../../typescript/packages/legacy/x402-next: dependencies: '@coinbase/cdp-sdk': specifier: ^1.22.0 @@ -508,7 +520,7 @@ importers: 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) - agent: + legacy/agent: dependencies: '@anthropic-ai/sdk': specifier: ^0.39.0 @@ -536,7 +548,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-fetch: specifier: workspace:* - version: link:../../../typescript/packages/x402-fetch + version: link:../../../../typescript/packages/legacy/x402-fetch zod: specifier: ^3.24.2 version: 3.25.76 @@ -575,7 +587,7 @@ importers: specifier: ^5.7.3 version: 5.9.2 - clients/axios: + legacy/clients/axios: dependencies: axios: specifier: ^1.7.9 @@ -585,7 +597,7 @@ importers: version: 16.6.1 x402-axios: specifier: workspace:* - version: link:../../../../typescript/packages/x402-axios + version: link:../../../../../typescript/packages/legacy/x402-axios devDependencies: '@eslint/js': specifier: ^9.24.0 @@ -618,7 +630,7 @@ importers: specifier: ^5.3.0 version: 5.9.2 - clients/cdp-sdk: + legacy/clients/cdp-sdk: dependencies: '@coinbase/cdp-sdk': specifier: ^1.16.0 @@ -634,7 +646,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-axios: specifier: workspace:* - version: link:../../../../typescript/packages/x402-axios + version: link:../../../../../typescript/packages/legacy/x402-axios devDependencies: '@eslint/js': specifier: ^9.24.0 @@ -667,7 +679,7 @@ importers: specifier: ^5.3.0 version: 5.9.2 - clients/chainlink-vrf-nft: + legacy/clients/chainlink-vrf-nft: dependencies: '@hono/node-server': specifier: ^1.13.8 @@ -685,11 +697,11 @@ importers: 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) 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) + specifier: workspace:* + version: link:../../../../../typescript/packages/legacy/x402 x402-axios: specifier: workspace:* - version: link:../../../../typescript/packages/x402-axios + version: link:../../../../../typescript/packages/legacy/x402-axios devDependencies: '@types/node': specifier: ^22.13.5 @@ -698,14 +710,14 @@ importers: specifier: ^4.19.3 version: 4.20.4 - clients/fetch: + legacy/clients/fetch: dependencies: dotenv: specifier: ^16.4.7 version: 16.6.1 x402-fetch: specifier: workspace:* - version: link:../../../../typescript/packages/x402-fetch + version: link:../../../../../typescript/packages/legacy/x402-fetch devDependencies: '@eslint/js': specifier: ^9.24.0 @@ -738,11 +750,11 @@ importers: specifier: ^5.3.0 version: 5.9.2 - discovery: + legacy/discovery: dependencies: '@coinbase/x402': specifier: workspace:* - version: link:../../../typescript/packages/coinbase-x402 + version: link:../../../../typescript/packages/legacy/coinbase-x402 axios: specifier: ^1.7.9 version: 1.11.0 @@ -751,7 +763,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: workspace:* - version: link:../../../typescript/packages/x402 + version: link:../../../../typescript/packages/legacy/x402 devDependencies: '@eslint/js': specifier: ^9.24.0 @@ -784,7 +796,7 @@ importers: specifier: ^5.3.0 version: 5.9.2 - dynamic_agent: + legacy/dynamic_agent: dependencies: '@anthropic-ai/sdk': specifier: ^0.39.0 @@ -857,7 +869,7 @@ importers: specifier: ^5.3.0 version: 5.9.2 - facilitator: + legacy/facilitator: dependencies: dotenv: specifier: ^16.4.7 @@ -867,7 +879,7 @@ importers: version: 4.21.2 x402: specifier: workspace:* - version: link:../../../typescript/packages/x402 + version: link:../../../../typescript/packages/legacy/x402 devDependencies: '@eslint/js': specifier: ^9.24.0 @@ -900,7 +912,7 @@ importers: specifier: ^5.3.0 version: 5.9.2 - fullstack/auth_based_pricing: + legacy/fullstack/auth_based_pricing: dependencies: '@coinbase/x402': specifier: ^0.3.3 @@ -946,20 +958,20 @@ importers: specifier: ^5.4.5 version: 5.9.2 - fullstack/browser-wallet-example: + legacy/fullstack/browser-wallet-example: devDependencies: concurrently: specifier: ^8.2.2 version: 8.2.2 - fullstack/farcaster-miniapp: + legacy/fullstack/farcaster-miniapp: 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: 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.6(@solana/sysvars@2.3.0(typescript@5.9.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) '@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) @@ -995,7 +1007,7 @@ importers: 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 + version: link:../../../../../typescript/packages/legacy/x402-next devDependencies: '@types/node': specifier: ^20.17.30 @@ -1037,11 +1049,11 @@ importers: specifier: ^5 version: 5.9.2 - fullstack/mainnet: + legacy/fullstack/mainnet: dependencies: '@coinbase/x402': specifier: workspace:* - version: link:../../../../typescript/packages/coinbase-x402 + version: link:../../../../../typescript/packages/legacy/coinbase-x402 '@heroicons/react': specifier: ^2.2.0 version: 2.2.0(react@19.1.1) @@ -1059,7 +1071,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-next: specifier: workspace:* - version: link:../../../../typescript/packages/x402-next + version: link:../../../../../typescript/packages/legacy/x402-next devDependencies: '@eslint/js': specifier: ^9.24.0 @@ -1110,11 +1122,11 @@ importers: specifier: ^5 version: 5.9.2 - fullstack/next: + legacy/fullstack/next: dependencies: '@coinbase/x402': specifier: workspace:* - version: link:../../../../typescript/packages/coinbase-x402 + version: link:../../../../../typescript/packages/legacy/coinbase-x402 '@heroicons/react': specifier: ^2.2.0 version: 2.2.0(react@19.1.1) @@ -1132,7 +1144,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-next: specifier: workspace:* - version: link:../../../../typescript/packages/x402-next + version: link:../../../../../typescript/packages/legacy/x402-next devDependencies: '@eslint/js': specifier: ^9.24.0 @@ -1183,11 +1195,11 @@ importers: specifier: ^5 version: 5.9.2 - fullstack/next-advanced: + legacy/fullstack/next-advanced: 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)(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)(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 +1220,7 @@ importers: 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 + version: link:../../../../../typescript/packages/legacy/x402 devDependencies: '@types/node': specifier: ^20 @@ -1235,7 +1247,7 @@ importers: specifier: ^5 version: 5.9.2 - mcp-embedded-wallet: + legacy/mcp-embedded-wallet: dependencies: '@coinbase/cdp-core': specifier: ^0.0.18 @@ -1248,7 +1260,7 @@ importers: 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 + version: link:../../../../typescript/packages/legacy/coinbase-x402 '@modelcontextprotocol/sdk': specifier: ^1.15.1 version: 1.17.3 @@ -1287,10 +1299,10 @@ importers: version: 3.17.0 x402: specifier: workspace:* - version: link:../../../typescript/packages/x402 + version: link:../../../../typescript/packages/legacy/x402 x402-axios: specifier: workspace:* - version: link:../../../typescript/packages/x402-axios + version: link:../../../../typescript/packages/legacy/x402-axios zod: specifier: ^3.23.8 version: 3.25.76 @@ -1353,7 +1365,7 @@ importers: 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) - servers/advanced: + legacy/servers/advanced: dependencies: dotenv: specifier: ^16.4.7 @@ -1363,7 +1375,7 @@ importers: version: 4.21.2 x402: specifier: workspace:* - version: link:../../../../typescript/packages/x402 + version: link:../../../../../typescript/packages/legacy/x402 devDependencies: '@eslint/js': specifier: ^9.24.0 @@ -1402,7 +1414,7 @@ importers: specifier: ^5.3.0 version: 5.9.2 - servers/express: + legacy/servers/express: dependencies: dotenv: specifier: ^16.4.7 @@ -1412,7 +1424,7 @@ importers: version: 4.21.2 x402-express: specifier: workspace:* - version: link:../../../../typescript/packages/x402-express + version: link:../../../../../typescript/packages/legacy/x402-express devDependencies: '@eslint/js': specifier: ^9.24.0 @@ -1451,7 +1463,7 @@ importers: specifier: ^5.3.0 version: 5.9.2 - servers/hono: + legacy/servers/hono: dependencies: '@hono/node-server': specifier: ^1.13.8 @@ -1464,7 +1476,7 @@ importers: version: 4.9.2 x402-hono: specifier: workspace:* - version: link:../../../../typescript/packages/x402-hono + version: link:../../../../../typescript/packages/legacy/x402-hono devDependencies: '@eslint/js': specifier: ^9.24.0 @@ -1500,11 +1512,11 @@ importers: specifier: ^5.3.0 version: 5.9.2 - servers/mainnet: + legacy/servers/mainnet: dependencies: '@coinbase/x402': specifier: workspace:* - version: link:../../../../typescript/packages/coinbase-x402 + version: link:../../../../../typescript/packages/legacy/coinbase-x402 dotenv: specifier: ^16.4.7 version: 16.6.1 @@ -1513,7 +1525,7 @@ importers: version: 4.21.2 x402-express: specifier: workspace:* - version: link:../../../../typescript/packages/x402-express + version: link:../../../../../typescript/packages/legacy/x402-express devDependencies: '@eslint/js': specifier: ^9.24.0 @@ -2214,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==} @@ -2223,8 +2243,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.6': + resolution: {integrity: sha512-a/Z4TK7ijR8WOqVtNtcOy0PxPF9kt+0ytvTJuNxjbjM14JcW2bQx9L2/8X7DwpkSuXJG8L01cukWUrLrh6v4zw==} '@colors/colors@1.6.0': resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} @@ -2732,12 +2752,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==} @@ -4513,6 +4548,10 @@ packages: peerDependencies: typescript: '>=5.3.3' + '@solana/wallet-standard-features@1.3.0': + resolution: {integrity: sha512-ZhpZtD+4VArf6RPitsVExvgkF+nGghd1rzPjd97GmBximpnt1rsUxMOEyoIEuH3XBxPyNB6Us7ha7RHWQR+abg==} + engines: {node: '>=16'} + '@solana/web3.js@1.98.4': resolution: {integrity: sha512-vv9lfnvjUsRiq//+j5pBdXig0IQdtzA0BRZ3bXEP4KaIyF1CcaydWqgyzQgfZMNIsWNWmG+AUHwPy4AHOD6gpw==} @@ -5001,6 +5040,18 @@ packages: typescript: optional: true + '@wallet-standard/app@1.1.0': + resolution: {integrity: sha512-3CijvrO9utx598kjr45hTbbeeykQrQfKmSnxeWOgU25TOEpvcipD/bYDQWIqUv1Oc6KK4YStokSMu/FBNecGUQ==} + engines: {node: '>=16'} + + '@wallet-standard/base@1.1.0': + resolution: {integrity: sha512-DJDQhjKmSNVLKWItoKThJS+CsJQjR9AOBOirBVT1F9YpRyC9oYHE+ZnSf8y8bxUphtKqdQMPVQ2mHohYdRvDVQ==} + engines: {node: '>=16'} + + '@wallet-standard/features@1.1.0': + resolution: {integrity: sha512-hiEivWNztx73s+7iLxsuD1sOJ28xtRix58W7Xnz4XzzA/pF0+aicnWgjOdA10doVDEDZdUuZCIIqG96SFNlDUg==} + engines: {node: '>=16'} + '@walletconnect/core@2.21.0': resolution: {integrity: sha512-o6R7Ua4myxR8aRUAJ1z3gT9nM+jd2B2mfamu6arzy1Cc6vi10fIwFWb6vg3bC8xJ6o9H3n/cN5TOW3aA9Y1XVw==} engines: {node: '>=18'} @@ -8878,9 +8929,15 @@ packages: resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} engines: {node: ^14.18.0 || >=16.0.0} + tabbable@6.3.0: + resolution: {integrity: sha512-EIHvdY5bPLuWForiR/AN2Bxngzpuwn1is4asboytXtpTgsArc+WmSJKVLlhdh71u7jFcryDqB2A8lQvj78MkyQ==} + 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'} @@ -9339,6 +9396,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'} @@ -9719,11 +9782,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@file:../../typescript/packages/x402: - resolution: {directory: ../../typescript/packages/x402, type: directory} + x402@0.6.6: + resolution: {integrity: sha512-gKkxqKBT0mH7fSLld6Mz9ML52dmu1XeOPhVtiUCA3EzkfY6p0EJ3ijKhIKN0Jh8Q6kVXrFlJ/4iAUS1dNDA2lA==} xml-name-validator@5.0.0: resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} @@ -10843,7 +10903,7 @@ snapshots: '@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.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)) + '@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.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 @@ -10886,48 +10946,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)': + '@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/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-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)) + '@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)) + '@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: 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)(@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 + - 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)(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)(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)(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)(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 - - db0 - encoding - immer - - ioredis - - supports-color - typescript - - uploadthing - use-sync-external-store - utf-8-validate - zod @@ -11000,11 +11082,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.6(@solana/sysvars@2.3.0(typescript@5.9.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: '@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) + x402: 0.6.6(@solana/sysvars@2.3.0(typescript@5.9.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) zod: 3.25.76 transitivePeerDependencies: - '@azure/app-configuration' @@ -11018,6 +11100,7 @@ snapshots: - '@netlify/blobs' - '@planetscale/database' - '@react-native-async-storage/async-storage' + - '@solana/sysvars' - '@tanstack/query-core' - '@tanstack/react-query' - '@types/react' @@ -11037,6 +11120,7 @@ snapshots: - typescript - uploadthing - utf-8-validate + - ws '@colors/colors@1.6.0': {} @@ -11175,7 +11259,7 @@ snapshots: '@electron/universal@2.0.1': dependencies: - '@electron/asar': 3.2.18 + '@electron/asar': 3.4.1 '@malept/cross-spawn-promise': 2.0.0 debug: 4.4.1 dir-compare: 4.2.0 @@ -11516,16 +11600,10 @@ 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))': - 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-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.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)': @@ -11549,12 +11627,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.3.0 + '@floating-ui/utils@0.2.10': {} '@gar/promisify@1.1.3': {} @@ -12270,6 +12373,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) @@ -12336,12 +12448,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 @@ -12362,6 +12492,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 @@ -12384,12 +12520,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 @@ -12403,6 +12567,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 @@ -12418,12 +12595,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) @@ -12435,6 +12633,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 @@ -12477,6 +12686,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) @@ -12512,6 +12728,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 @@ -12611,6 +12853,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) @@ -12629,6 +12894,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) @@ -12639,6 +12922,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) @@ -12649,6 +12942,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) @@ -12658,6 +12961,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) @@ -12703,6 +13015,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 @@ -12784,6 +13113,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 @@ -12815,6 +13151,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 @@ -12835,6 +13187,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 @@ -12902,6 +13274,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) @@ -12910,6 +13288,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) @@ -12917,6 +13303,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) @@ -12924,6 +13317,13 @@ snapshots: optionalDependencies: '@types/react': 19.1.10 + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.1.10)(react@19.1.1)': + dependencies: + '@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 @@ -12937,6 +13337,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 @@ -12950,6 +13356,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) @@ -12957,6 +13370,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) @@ -12966,6 +13386,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)': @@ -12997,439 +13426,15 @@ snapshots: 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) 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)': - 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) - 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(@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) - 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' - - '@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(@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.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.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(@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) - '@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-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) - lit: 3.3.0 - valtio: 1.13.2(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-polyfills@1.7.8': - 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)': - 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-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(@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) - '@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-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) - 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-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.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 - 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(@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) - '@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-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 + - bufferutil - typescript - - uploadthing - 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-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-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.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) @@ -13460,16 +13465,14 @@ 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-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.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) + '@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.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' @@ -13497,16 +13500,18 @@ 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-polyfills@1.7.8': + 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)': 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-polyfills': 1.7.8 + '@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) - '@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) + lit: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -13532,34 +13537,16 @@ snapshots: - typescript - uploadthing - utf-8-validate + - valtio - 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 - - 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-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.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.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.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.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) + lit: 3.3.0 + qrcode: 1.5.3 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -13587,19 +13574,14 @@ 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-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.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-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-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 + '@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) transitivePeerDependencies: @@ -13629,20 +13611,31 @@ snapshots: - 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)': + '@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@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-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) + '@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(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-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-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.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) + 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' @@ -13777,7 +13770,7 @@ snapshots: '@scure/bip32@1.7.0': dependencies: - '@noble/curves': 1.9.6 + '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 @@ -13829,7 +13822,7 @@ snapshots: '@solana-program/compute-budget@0.8.0(@solana/kit@2.3.0(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-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: @@ -13838,7 +13831,7 @@ 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))': 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)))': @@ -13847,7 +13840,7 @@ snapshots: '@solana-program/token@0.5.1(@solana/kit@2.3.0(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/accounts@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': dependencies: @@ -14054,31 +14047,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 @@ -14394,23 +14362,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) @@ -14444,6 +14395,11 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder + '@solana/wallet-standard-features@1.3.0': + dependencies: + '@wallet-standard/base': 1.1.0 + '@wallet-standard/features': 1.1.0 + '@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 @@ -14696,7 +14652,7 @@ snapshots: '@types/node-fetch@2.6.13': dependencies: - '@types/node': 20.19.11 + '@types/node': 22.17.2 form-data: 4.0.4 '@types/node@12.20.55': {} @@ -15012,13 +14968,13 @@ snapshots: chai: 5.3.1 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@7.1.3(@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.17 optionalDependencies: - vite: 6.3.5(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) + vite: 7.1.3(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) '@vitest/pretty-format@3.2.4': dependencies: @@ -15132,50 +15088,7 @@ 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)': + '@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)(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) @@ -15184,7 +15097,7 @@ snapshots: '@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(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.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) optionalDependencies: @@ -15248,6 +15161,16 @@ snapshots: - react - use-sync-external-store + '@wallet-standard/app@1.1.0': + dependencies: + '@wallet-standard/base': 1.1.0 + + '@wallet-standard/base@1.1.0': {} + + '@wallet-standard/features@1.1.0': + dependencies: + '@wallet-standard/base': 1.1.0 + '@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 @@ -15266,91 +15189,7 @@ snapshots: '@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/kv' - - aws4fetch - - bufferutil - - db0 - - ioredis - - typescript - - uploadthing - - 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)': - 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/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' - - '@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 - - ioredis - - typescript - - uploadthing - - utf-8-validate - - zod - - '@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.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.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 + uint8arrays: 3.1.0 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -15363,34 +15202,37 @@ snapshots: - '@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(@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/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.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/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/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/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/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/window-getters': 1.0.1 + es-toolkit: 1.33.0 events: 3.3.0 + uint8arrays: 3.1.0 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -15403,24 +15245,25 @@ snapshots: - '@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)': + '@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(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.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 @@ -15428,7 +15271,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: @@ -15719,45 +15562,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 @@ -15797,45 +15601,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 @@ -15950,6 +15715,11 @@ snapshots: typescript: 5.9.2 zod: 3.25.76 + abitype@1.0.9(typescript@5.9.2)(zod@3.22.4): + optionalDependencies: + typescript: 5.9.2 + zod: 3.22.4 + abitype@1.0.9(typescript@5.9.2)(zod@3.25.76): optionalDependencies: typescript: 5.9.2 @@ -16892,10 +16662,6 @@ snapshots: dependencies: 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: - valtio: 1.13.2(react@19.1.1) - destr@2.0.5: {} destroy@1.2.0: {} @@ -19331,11 +19097,11 @@ snapshots: ox@0.6.7(typescript@5.9.2)(zod@3.25.76): dependencies: '@adraffy/ens-normalize': 1.11.0 - '@noble/curves': 1.8.1 + '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 - '@scure/bip32': 1.6.2 - '@scure/bip39': 1.5.4 - abitype: 1.0.8(typescript@5.9.2)(zod@3.25.76) + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.0.9(typescript@5.9.2)(zod@3.25.76) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.2 @@ -19375,11 +19141,11 @@ snapshots: dependencies: '@adraffy/ens-normalize': 1.11.0 '@noble/ciphers': 1.3.0 - '@noble/curves': 1.9.6 + '@noble/curves': 1.9.7 '@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.0.9(typescript@5.9.2)(zod@3.22.4) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.2 @@ -19390,11 +19156,11 @@ snapshots: dependencies: '@adraffy/ens-normalize': 1.11.0 '@noble/ciphers': 1.3.0 - '@noble/curves': 1.9.6 + '@noble/curves': 1.9.7 '@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.0.9(typescript@5.9.2)(zod@3.25.76) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.2 @@ -19826,6 +19592,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 @@ -19837,6 +19611,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 @@ -19845,6 +19630,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 @@ -20571,8 +20364,12 @@ snapshots: dependencies: '@pkgr/core': 0.2.9 + tabbable@6.3.0: {} + tailwind-merge@2.6.0: {} + tailwind-merge@3.3.1: {} + tailwindcss@3.4.17: dependencies: '@alloc/quick-lru': 5.2.0 @@ -20994,6 +20791,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 @@ -21002,6 +20806,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 @@ -21019,6 +20831,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 @@ -21054,14 +20871,6 @@ snapshots: '@types/react': 19.1.10 react: 19.1.1 - valtio@1.13.2(react@19.1.1): - dependencies: - derive-valtio: 0.1.0(valtio@1.13.2(react@19.1.1)) - proxy-compare: 2.6.0 - use-sync-external-store: 1.2.0(react@19.1.1) - optionalDependencies: - react: 19.1.1 - vary@1.1.2: {} verror@1.10.1: @@ -21128,7 +20937,7 @@ snapshots: debug: 4.4.1 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: 7.1.3(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1) transitivePeerDependencies: - '@types/node' - jiti @@ -21169,6 +20978,21 @@ snapshots: tsx: 4.20.4 yaml: 2.8.1 + vite@7.1.3(@types/node@22.17.2)(jiti@1.21.7)(tsx@4.20.4)(yaml@2.8.1): + dependencies: + esbuild: 0.25.9 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.46.4 + tinyglobby: 0.2.14 + optionalDependencies: + '@types/node': 22.17.2 + fsevents: 2.3.3 + jiti: 1.21.7 + tsx: 4.20.4 + 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.9 @@ -21188,7 +21012,7 @@ snapshots: 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@7.1.3(@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 @@ -21206,7 +21030,7 @@ snapshots: tinyglobby: 0.2.14 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: 7.1.3(@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: @@ -21272,45 +21096,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)(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/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/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.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/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)(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) @@ -21645,51 +21431,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): - 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) - 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/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - immer - - ioredis - - react - - supports-color - - typescript - - 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@0.6.6(@solana/sysvars@2.3.0(typescript@5.9.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: '@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/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) + 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' diff --git a/examples/typescript/pnpm-workspace.yaml b/examples/typescript/pnpm-workspace.yaml index c2591ea08..8626e6e8a 100644 --- a/examples/typescript/pnpm-workspace.yaml +++ b/examples/typescript/pnpm-workspace.yaml @@ -1,11 +1,11 @@ packages: - - "facilitator" - - "servers/*" - - "clients/*" - - "fullstack/*" - - "dynamic_agent" - - "agent" - - "mcp-embedded-wallet" - - "mpc" - - "discovery" - - "../../typescript/packages/*" + - "legacy/facilitator" + - "legacy/servers/*" + - "legacy/clients/*" + - "legacy/fullstack/*" + - "legacy/dynamic_agent" + - "legacy/agent" + - "legacy/mcp-embedded-wallet" + - "legacy/mpc" + - "legacy/discovery" + - "../../typescript/packages/legacy/*" diff --git a/go/.gitignore b/go/.gitignore new file mode 100644 index 000000000..8c53565ff --- /dev/null +++ b/go/.gitignore @@ -0,0 +1,53 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool +*.out +coverage.html + +# Dependency directories +vendor/ + +# Go workspace file +go.work + +# IDE files +.idea/ +*.swp +*.swo +*~ +.vscode/ +*.iml + +# OS files +.DS_Store +Thumbs.db + +# Build artifacts +dist/ +build/ + +# Environment files +.env +.env.local + +# Debug files +debug +__debug_bin + +# Temporary files +*.tmp +*.bak +*.backup +*.log + +# Generated files +*_gen.go +*_mock.go diff --git a/go/Makefile b/go/Makefile new file mode 100644 index 000000000..2cca79d70 --- /dev/null +++ b/go/Makefile @@ -0,0 +1,125 @@ +.PHONY: all build test lint fmt clean install help + +# Variables +GOPATH := $(shell go env GOPATH) +GOBIN := $(GOPATH)/bin +GOLANGCI_LINT := $(GOBIN)/golangci-lint +MOCKGEN := $(GOBIN)/mockgen + +# Default target +all: fmt lint test build + +## help: Show this help message +help: + @echo 'Usage:' + @sed -n 's/^##//p' ${MAKEFILE_LIST} | column -t -s ':' | sed -e 's/^/ /' + +## build: Build the SDK +build: + @echo "Building SDK..." + @go build -v ./... + +## test: Run unit tests +test: + @echo "Running tests..." + @go test -race -cover ./... + +## test-cover: Run tests with coverage report +test-cover: + @echo "Running tests with coverage..." + @go test -race -coverprofile=coverage.out -covermode=atomic ./... + @go tool cover -html=coverage.out -o coverage.html + @echo "Coverage report generated: coverage.html" + +## test-integration: Run integration tests +test-integration: + @echo "Running integration tests..." + @go test -race -tags=integration ./test/integration/... + +## test-e2e: Run end-to-end tests +test-e2e: + @echo "Running e2e tests..." + @go test -race -tags=e2e ./test/e2e/... + +## lint: Run linter +lint: $(GOLANGCI_LINT) + @echo "Running linter..." + @$(GOLANGCI_LINT) run ./... + +## fmt: Format code +fmt: + @echo "Formatting code..." + @go fmt ./... + @goimports -w . + +## clean: Clean build artifacts +clean: + @echo "Cleaning..." + @go clean -cache + @rm -f coverage.out coverage.html + @rm -rf dist/ + +## install: Install the SDK +install: + @echo "Installing SDK..." + @go install ./... + +## deps: Install dependencies +deps: + @echo "Installing dependencies..." + @go mod download + @go mod tidy + +## deps-dev: Install development dependencies +deps-dev: $(GOLANGCI_LINT) $(MOCKGEN) + @echo "Development dependencies installed" + +## generate: Generate code (mocks, etc.) +generate: $(MOCKGEN) + @echo "Generating code..." + @go generate ./... + +## docs: Generate documentation +docs: + @echo "Generating documentation..." + @godoc -http=:6060 & + @echo "Documentation server started at http://localhost:6060/pkg/github.com/coinbase/x402-go/v2/" + +## example-client: Run client example +example-client: + @echo "Running client example..." + @go run examples/client/basic/main.go + +## example-server: Run server example +example-server: + @echo "Running server example..." + @go run examples/server/gin/main.go + +## example-facilitator: Run facilitator example +example-facilitator: + @echo "Running facilitator example..." + @go run examples/facilitator/local/main.go + +## verify: Run all checks (fmt, lint, test) +verify: fmt lint test + +## release: Prepare for release +release: clean verify build + @echo "Ready for release!" + +# Tool installations +$(GOLANGCI_LINT): + @echo "Installing golangci-lint..." + @go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest + +$(MOCKGEN): + @echo "Installing mockgen..." + @go install github.com/golang/mock/mockgen@latest + +# Print variables for debugging +## vars: Print Makefile variables +vars: + @echo "GOPATH: $(GOPATH)" + @echo "GOBIN: $(GOBIN)" + @echo "GOLANGCI_LINT: $(GOLANGCI_LINT)" + @echo "MOCKGEN: $(MOCKGEN)" diff --git a/go/README.md b/go/README.md index 851fd5f2e..d19e769b4 100644 --- a/go/README.md +++ b/go/README.md @@ -1,47 +1,143 @@ -# Go x402 +# x402 Go SDK + +Go implementation of the x402 payment protocol for HTTP 402 Payment Required responses with cryptocurrency payments. ## Installation ```bash -go get github.com/coinbase/x402/go +go get github.com/coinbase/x402-go/v2 ``` -## Usage +## Quick Start -### Accepting x402 Payments with a [Gin](https://github.com/gin-gonic/gin) Resource Server +### Client Usage ```go package main import ( - "math/big" + "context" + "fmt" + "net/http" + + x402 "github.com/coinbase/x402-go/v2" + "github.com/coinbase/x402-go/v2/http" + "github.com/coinbase/x402-go/v2/mechanisms/evm" +) + +func main() { + // Create EVM signer + signer := evm.NewSigner(privateKey) + + // Create x402 HTTP client + client := x402http.NewHTTPClient( + x402http.WithScheme("eip155:8453", evm.NewExactClient(signer)), + ) + + // Wrap standard HTTP client + httpClient := x402http.WrapHTTPClient(http.DefaultClient, client) + + // Make request - payment handled automatically + resp, err := httpClient.Get("https://api.example.com/protected") + if err != nil { + panic(err) + } + defer resp.Body.Close() + + fmt.Println("Response:", resp.Status) +} +``` - x402gin "github.com/coinbase/x402/go/pkg/gin" - "github.com/gin-gonic/gin" +### Server Usage (Gin) + +```go +package main + +import ( + "github.com/gin-gonic/gin" + x402 "github.com/coinbase/x402-go/v2" + "github.com/coinbase/x402-go/v2/middleware/gin" + "github.com/coinbase/x402-go/v2/mechanisms/evm" ) func main() { - r := gin.Default() - - facilitatorConfig := &types.FacilitatorConfig{ - URL: "http://localhost:3000", - } - - r.GET( - "/joke", - x402gin.PaymentMiddleware( - big.NewFloat(0.0001), - "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", - x402gin.WithFacilitatorConfig(facilitatorConfig), - x402gin.WithResource("http://localhost:4021/joke"), - ), - func(c *gin.Context) { - c.JSON(200, gin.H{ - "joke": "Why do programmers prefer dark mode? Because light attracts bugs!", - }) - }, - ) - - r.Run(":4021") // Start the server on 0.0.0.0:4021 (for windows "localhost:4021") + r := gin.Default() + + // Configure payment routes + routes := x402gin.Routes{ + "GET /protected": { + Scheme: "exact", + PayTo: "0x...", + Price: "$0.001", + Network: "eip155:8453", + }, + } + + // Add payment middleware + r.Use(x402gin.PaymentMiddleware(routes, + x402gin.WithFacilitatorURL("https://facilitator.example.com"), + x402gin.WithScheme("eip155:8453", evm.NewExactService()), + )) + + r.GET("/protected", func(c *gin.Context) { + c.JSON(200, gin.H{"data": "protected resource"}) + }) + + r.Run(":8080") } ``` + +## Features + +- āœ… **Protocol v2 Support** - Full implementation of x402 protocol v2 +- āœ… **EVM Support** - Built-in EVM blockchain support with EIP-3009 +- āœ… **Framework Agnostic** - Core functionality with optional framework middleware +- āœ… **Tree-Shakeable** - Import only what you need +- āœ… **Type Safe** - Strong typing with Go generics +- āœ… **Context Support** - Proper context handling for cancellation +- āœ… **Concurrent Safe** - Thread-safe operations + +## Documentation + +- [Architecture](SDK_ARCHITECTURE.md) +- [Module Structure](MODULE_STRUCTURE.md) +- [API Reference](https://pkg.go.dev/github.com/coinbase/x402-go/v2) + +## Supported Frameworks + +- [x] Gin +- [ ] Echo +- [x] net/http (standard library) +- [ ] Fiber +- [ ] Chi + +## Supported Mechanisms + +- [x] EVM (Ethereum, Base, etc.) + - [x] Exact payment scheme (EIP-3009) +- [ ] Solana +- [ ] Bitcoin Lightning + +## Testing + +```bash +# Run all tests +make test + +# Run with coverage +make test-cover + +# Run integration tests +make test-integration + +# Run e2e tests +make test-e2e +``` + +## Contributing + +See [CONTRIBUTING.md](../CONTRIBUTING.md) + +## License + +MIT License - see [LICENSE](../LICENSE) for details diff --git a/go/SERVICE.md b/go/SERVICE.md new file mode 100644 index 000000000..e75a766db --- /dev/null +++ b/go/SERVICE.md @@ -0,0 +1,479 @@ +# SERVICE - x402 Resource Service Implementation + +The service is used by servers/APIs to protect resources with payment requirements. It creates 402 responses, verifies payments, and coordinates settlement with facilitators. + +```go +package x402 + +import ( + "context" + "fmt" + "sync" + "time" +) + +// ============================================================================ +// ResourceService - Used by SERVERS that want to charge for resources +// ============================================================================ + +// ResourceService manages payment requirements and verification for protected resources +// This is used by servers/APIs that want to charge for access +type ResourceService struct { + mu sync.RWMutex + + // Map of network -> scheme -> service implementation + schemes map[Network]map[string]SchemeNetworkService + + // Facilitator clients for payment verification/settlement + facilitatorClients []FacilitatorClient + + // Cache of supported payment kinds from facilitators + supportedCache *SupportedCache +} + +// SupportedCache caches facilitator capabilities +type SupportedCache struct { + mu sync.RWMutex + data map[string]SupportedResponse // key is facilitator identifier + expiry map[string]time.Time + ttl time.Duration +} + +// ResourceServiceOption configures the service +type ResourceServiceOption func(*ResourceService) + +// WithFacilitatorClient adds a facilitator client +func WithFacilitatorClient(client FacilitatorClient) ResourceServiceOption { + return func(s *ResourceService) { + s.facilitatorClients = append(s.facilitatorClients, client) + } +} + +// WithSchemeService registers a scheme service implementation +func WithSchemeService(network Network, service SchemeNetworkService) ResourceServiceOption { + return func(s *ResourceService) { + s.registerScheme(network, service) + } +} + +// WithCacheTTL sets the cache TTL for supported kinds +func WithCacheTTL(ttl time.Duration) ResourceServiceOption { + return func(s *ResourceService) { + s.supportedCache.ttl = ttl + } +} + +// NewResourceService creates a new resource service +func NewResourceService(opts ...ResourceServiceOption) *ResourceService { + s := &ResourceService{ + schemes: make(map[Network]map[string]SchemeNetworkService), + facilitatorClients: []FacilitatorClient{}, + supportedCache: &SupportedCache{ + data: make(map[string]SupportedResponse), + expiry: make(map[string]time.Time), + ttl: 5 * time.Minute, // Default 5 minute cache + }, + } + + for _, opt := range opts { + opt(s) + } + + // If no facilitator clients provided, this is an error for production + // but we'll allow it for testing + if len(s.facilitatorClients) == 0 { + // Log warning - in production should have at least one facilitator + } + + return s +} + +// ============================================================================ +// Initialization +// ============================================================================ + +// Initialize fetches supported payment kinds from all facilitators +// Should be called on startup to populate cache +func (s *ResourceService) Initialize(ctx context.Context) error { + var lastErr error + successCount := 0 + + for i, client := range s.facilitatorClients { + supported, err := client.GetSupported(ctx) + if err != nil { + lastErr = fmt.Errorf("facilitator %d: %w", i, err) + continue + } + + // Cache the supported kinds + key := fmt.Sprintf("facilitator_%d", i) + s.supportedCache.Set(key, supported) + successCount++ + } + + if successCount == 0 && lastErr != nil { + return fmt.Errorf("failed to initialize any facilitators: %w", lastErr) + } + + return nil +} + +// ============================================================================ +// Scheme Registration +// ============================================================================ + +// RegisterScheme registers a scheme service for a network +func (s *ResourceService) RegisterScheme(network Network, service SchemeNetworkService) *ResourceService { + return s.registerScheme(network, service) +} + +func (s *ResourceService) registerScheme(network Network, service SchemeNetworkService) *ResourceService { + s.mu.Lock() + defer s.mu.Unlock() + + if s.schemes[network] == nil { + s.schemes[network] = make(map[string]SchemeNetworkService) + } + + s.schemes[network][service.Scheme()] = service + + return s +} + +// ============================================================================ +// Payment Requirements Building +// ============================================================================ + +// BuildPaymentRequirements creates payment requirements for a resource +func (s *ResourceService) BuildPaymentRequirements(ctx context.Context, config ResourceConfig) ([]PaymentRequirements, error) { + s.mu.RLock() + defer s.mu.RUnlock() + + // Find the scheme service + service := s.findSchemeService(config.Network, config.Scheme) + if service == nil { + return nil, &PaymentError{ + Code: ErrCodeUnsupportedScheme, + Message: fmt.Sprintf("no service registered for scheme %s on network %s", config.Scheme, config.Network), + } + } + + // Get supported kinds from facilitators + supportedKind := s.findSupportedKind(ProtocolVersion, config.Network, config.Scheme) + if supportedKind == nil { + return nil, &PaymentError{ + Code: ErrCodeUnsupportedNetwork, + Message: fmt.Sprintf("facilitator does not support %s on %s", config.Scheme, config.Network), + Details: map[string]interface{}{ + "hint": "call Initialize() to fetch supported kinds from facilitators", + }, + } + } + + // Parse the price using the scheme's parser + assetAmount, err := service.ParsePrice(config.Price, config.Network) + if err != nil { + return nil, fmt.Errorf("failed to parse price: %w", err) + } + + // Build base requirements + baseRequirements := PaymentRequirements{ + Scheme: config.Scheme, + Network: config.Network, + Asset: assetAmount.Asset, + Amount: assetAmount.Amount, + PayTo: config.PayTo, + MaxTimeoutSeconds: config.MaxTimeoutSeconds, + Extra: assetAmount.Extra, + } + + // Set default timeout if not specified + if baseRequirements.MaxTimeoutSeconds == 0 { + baseRequirements.MaxTimeoutSeconds = 300 // 5 minutes default + } + + // Get facilitator extensions + extensions := s.getFacilitatorExtensions(ProtocolVersion, config.Network, config.Scheme) + + // Enhance with scheme-specific details + enhanced, err := service.EnhancePaymentRequirements(ctx, baseRequirements, *supportedKind, extensions) + if err != nil { + return nil, fmt.Errorf("failed to enhance payment requirements: %w", err) + } + + return []PaymentRequirements{enhanced}, nil +} + +// CreatePaymentRequiredResponse creates a 402 response +func (s *ResourceService) CreatePaymentRequiredResponse( + requirements []PaymentRequirements, + info ResourceInfo, + errorMsg string, + extensions map[string]interface{}, +) PaymentRequired { + response := PaymentRequired{ + X402Version: ProtocolVersion, + Error: errorMsg, + Resource: info, + Accepts: requirements, + Extensions: extensions, + } + + if errorMsg == "" { + response.Error = "Payment required" + } + + return response +} + +// ============================================================================ +// Payment Verification & Settlement +// ============================================================================ + +// VerifyPayment verifies a payment against requirements +func (s *ResourceService) VerifyPayment(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (VerifyResponse, error) { + // Validate inputs + if err := ValidatePaymentPayload(payload); err != nil { + return VerifyResponse{IsValid: false, InvalidReason: err.Error()}, err + } + + if err := ValidatePaymentRequirements(requirements); err != nil { + return VerifyResponse{IsValid: false, InvalidReason: err.Error()}, err + } + + // Find appropriate facilitator + facilitator := s.findFacilitatorForPayment(payload.X402Version, requirements.Network, requirements.Scheme) + if facilitator == nil { + // Try all facilitators as fallback + for _, client := range s.facilitatorClients { + resp, err := client.Verify(ctx, payload, requirements) + if err == nil { + return resp, nil + } + } + + return VerifyResponse{ + IsValid: false, + InvalidReason: "no facilitator available for verification", + }, &PaymentError{ + Code: ErrCodeUnsupportedNetwork, + Message: "no facilitator supports this payment type", + } + } + + return facilitator.Verify(ctx, payload, requirements) +} + +// SettlePayment settles a verified payment +func (s *ResourceService) SettlePayment(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (SettleResponse, error) { + // Find appropriate facilitator + facilitator := s.findFacilitatorForPayment(payload.X402Version, requirements.Network, requirements.Scheme) + if facilitator == nil { + // Try all facilitators as fallback + for _, client := range s.facilitatorClients { + resp, err := client.Settle(ctx, payload, requirements) + if err == nil { + return resp, nil + } + } + + return SettleResponse{ + Success: false, + ErrorReason: "no facilitator available for settlement", + }, &PaymentError{ + Code: ErrCodeSettlementFailed, + Message: "no facilitator supports this payment type", + } + } + + return facilitator.Settle(ctx, payload, requirements) +} + +// FindMatchingRequirements finds requirements that match a payment payload +func (s *ResourceService) FindMatchingRequirements(available []PaymentRequirements, payload PaymentPayload) *PaymentRequirements { + switch payload.X402Version { + case 2: + // V2: match by accepted requirements + for _, req := range available { + if DeepEqual(req, payload.Accepted) { + return &req + } + } + case 1: + // V1: match by scheme and network + for _, req := range available { + if req.Scheme == payload.Scheme && req.Network == payload.Network { + return &req + } + } + } + return nil +} + +// ============================================================================ +// Helper Methods +// ============================================================================ + +// findSchemeService finds a registered service for network/scheme +func (s *ResourceService) findSchemeService(network Network, scheme string) SchemeNetworkService { + // Try exact match + if schemes, exists := s.schemes[network]; exists { + if service, exists := schemes[scheme]; exists { + return service + } + } + + // Try pattern matching + for registeredNetwork, schemes := range s.schemes { + if network.Match(registeredNetwork) { + if service, exists := schemes[scheme]; exists { + return service + } + } + } + + return nil +} + +// findSupportedKind finds a supported kind from cache +func (s *ResourceService) findSupportedKind(version int, network Network, scheme string) *SupportedKind { + s.supportedCache.mu.RLock() + defer s.supportedCache.mu.RUnlock() + + for key, supported := range s.supportedCache.data { + // Check if cache entry is still valid + if expiry, exists := s.supportedCache.expiry[key]; exists { + if time.Now().After(expiry) { + continue // Skip expired entries + } + } + + // Look for matching kind + for _, kind := range supported.Kinds { + if kind.X402Version == version && + kind.Scheme == scheme && + Network(kind.Network).Match(network) { + return &SupportedKind{ + X402Version: kind.X402Version, + Scheme: kind.Scheme, + Network: kind.Network, + Extra: kind.Extra, + } + } + } + } + + return nil +} + +// getFacilitatorExtensions gets extensions for a payment type +func (s *ResourceService) getFacilitatorExtensions(version int, network Network, scheme string) []string { + s.supportedCache.mu.RLock() + defer s.supportedCache.mu.RUnlock() + + for _, supported := range s.supportedCache.data { + for _, kind := range supported.Kinds { + if kind.X402Version == version && + kind.Scheme == scheme && + Network(kind.Network).Match(network) { + return supported.Extensions + } + } + } + + return []string{} +} + +// findFacilitatorForPayment finds the facilitator that supports a payment type +func (s *ResourceService) findFacilitatorForPayment(version int, network Network, scheme string) FacilitatorClient { + // This is simplified - in practice, we'd match against cached supported kinds + // to find the right facilitator + if len(s.facilitatorClients) > 0 { + return s.facilitatorClients[0] + } + return nil +} + +// ============================================================================ +// Cache Methods +// ============================================================================ + +// Set adds an item to the cache +func (c *SupportedCache) Set(key string, value SupportedResponse) { + c.mu.Lock() + defer c.mu.Unlock() + + c.data[key] = value + c.expiry[key] = time.Now().Add(c.ttl) +} + +// Clear clears the cache +func (c *SupportedCache) Clear() { + c.mu.Lock() + defer c.mu.Unlock() + + c.data = make(map[string]SupportedResponse) + c.expiry = make(map[string]time.Time) +} +``` + +## Usage Example + +```go +// Example: Creating a service for a protected API +import ( + x402 "github.com/coinbase/x402-go/v2" + "github.com/coinbase/x402-go/v2/mechanisms/evm" +) + +func main() { + // Create service with EVM support + service := x402.NewResourceService( + // Add facilitator client(s) + x402.WithFacilitatorClient(facilitatorClient), + + // Register scheme services + x402.WithSchemeService("eip155:8453", evm.NewExactService()), + x402.WithSchemeService("eip155:1", evm.NewExactService()), + ) + + // Initialize to fetch supported kinds + if err := service.Initialize(ctx); err != nil { + log.Fatal(err) + } + + // Build payment requirements for a resource + config := ResourceConfig{ + Scheme: "exact", + PayTo: "0x...", + Price: "$0.10", + Network: "eip155:8453", + } + + requirements, err := service.BuildPaymentRequirements(ctx, config) + if err != nil { + // Handle error + } + + // Create 402 response + response := service.CreatePaymentRequiredResponse( + requirements, + ResourceInfo{ + URL: "https://api.example.com/data", + Description: "Premium API data", + MimeType: "application/json", + }, + "Payment required for access", + nil, + ) + + // Later, verify payment from client + verifyResp, err := service.VerifyPayment(ctx, paymentPayload, requirements[0]) + if verifyResp.IsValid { + // Payment is valid, provide resource + + // Then settle payment + settleResp, err := service.SettlePayment(ctx, paymentPayload, requirements[0]) + } +} +``` diff --git a/go/TODO.md b/go/TODO.md new file mode 100644 index 000000000..f917806c2 --- /dev/null +++ b/go/TODO.md @@ -0,0 +1,43 @@ +# x402 Go SDK + +Go implementation of the x402 payment protocol for HTTP 402 Payment Required responses with cryptocurrency payments. + +## TODO + +The Go SDK for x402 is currently in development. The implementation will follow the patterns established by the TypeScript core package while embracing idiomatic Go conventions. + +### Proposed Package Structure + +``` +/go/x402 + /core # Core protocol implementation + /types # Shared type definitions + /mechanisms # Implementations + /evm # EVM blockchain implementation + /svm # Solana blockchain implementation + /extensions # Protocol extensions + /bazaar # Resource discovery extension + /sign_in_with_x # Authentication extension + /client # Client implementations + /x402_client # Base client + /x402_http_client # HTTP-specific client + /server # Server implementations + /x402_resource_server # Core server logic + /x402_http_resource_server # HTTP server + /paywall # Paywall HTML generation + /gin # Gin framework middleware + /facilitator # Facilitator components + /x402_facilitator # Local facilitator + /http # HTTP adapters + /gin # Gin-specific adapter +``` + +### Server Framework Support + +The SDK will provide middleware implementations for popular Go web frameworks, starting with **Gin**. + +### Client HTTP Library Support + +For client-side payment handling, we'll implement interceptors for popular client libraries. + +The Go SDK will maintain API compatibility with the TypeScript and Python core package concepts while providing a native Go developer experience. diff --git a/go/client.go b/go/client.go new file mode 100644 index 000000000..dd1a63cb7 --- /dev/null +++ b/go/client.go @@ -0,0 +1,215 @@ +package x402 + +import ( + "context" + "fmt" + "sync" +) + +// x402Client manages payment mechanisms and creates payment payloads +// This is used by applications that need to make payments (have wallets/signers) +type x402Client struct { + mu sync.RWMutex + + // Nested map: version -> network -> scheme -> client implementation + // This allows multiple versions and network patterns + schemes map[int]map[Network]map[string]SchemeNetworkClient + + // Function to select payment requirements when multiple options exist + requirementsSelector PaymentRequirementsSelector +} + +// PaymentRequirementsSelector chooses which payment option to use +type PaymentRequirementsSelector func(version int, requirements []PaymentRequirements) PaymentRequirements + +// ClientOption configures the client +type ClientOption func(*x402Client) + +// WithPaymentSelector sets a custom payment requirements selector +func WithPaymentSelector(selector PaymentRequirementsSelector) ClientOption { + return func(c *x402Client) { + c.requirementsSelector = selector + } +} + +// WithScheme registers a payment mechanism at creation time +func WithScheme(version int, network Network, client SchemeNetworkClient) ClientOption { + return func(c *x402Client) { + c.registerScheme(version, network, client) + } +} + +// Newx402Client creates a new x402 client +func Newx402Client(opts ...ClientOption) *x402Client { + c := &x402Client{ + schemes: make(map[int]map[Network]map[string]SchemeNetworkClient), + requirementsSelector: defaultPaymentSelector, + } + + for _, opt := range opts { + opt(c) + } + + return c +} + +// defaultPaymentSelector chooses the first available payment option +func defaultPaymentSelector(version int, requirements []PaymentRequirements) PaymentRequirements { + if len(requirements) == 0 { + panic("no payment requirements available") + } + return requirements[0] +} + +// RegisterScheme registers a payment mechanism for protocol v2 +func (c *x402Client) RegisterScheme(network Network, client SchemeNetworkClient) *x402Client { + return c.registerScheme(ProtocolVersion, network, client) +} + +// RegisterSchemeV1 registers a payment mechanism for protocol v1 +func (c *x402Client) RegisterSchemeV1(network Network, client SchemeNetworkClient) *x402Client { + return c.registerScheme(ProtocolVersionV1, network, client) +} + +// registerScheme internal method to register schemes +func (c *x402Client) registerScheme(version int, network Network, client SchemeNetworkClient) *x402Client { + c.mu.Lock() + defer c.mu.Unlock() + + // Initialize nested maps if needed + if c.schemes[version] == nil { + c.schemes[version] = make(map[Network]map[string]SchemeNetworkClient) + } + if c.schemes[version][network] == nil { + c.schemes[version][network] = make(map[string]SchemeNetworkClient) + } + + // Register the client for this scheme + c.schemes[version][network][client.Scheme()] = client + + return c +} + +// SelectPaymentRequirements chooses which payment requirements to use +// This filters requirements to only those the client can fulfill +func (c *x402Client) SelectPaymentRequirements(version int, requirements []PaymentRequirements) (PaymentRequirements, error) { + c.mu.RLock() + defer c.mu.RUnlock() + + versionSchemes, exists := c.schemes[version] + if !exists { + return PaymentRequirements{}, fmt.Errorf("no schemes registered for x402 version %d", version) + } + + // Filter to only supported requirements + var supported []PaymentRequirements + for _, req := range requirements { + schemeMap := findSchemesByNetwork(versionSchemes, req.Network) + if schemeMap != nil { + if _, hasScheme := schemeMap[req.Scheme]; hasScheme { + supported = append(supported, req) + } + } + } + + if len(supported) == 0 { + return PaymentRequirements{}, &PaymentError{ + Code: ErrCodeUnsupportedScheme, + Message: "no supported payment schemes available", + Details: map[string]interface{}{ + "version": version, + "requirements": requirements, + }, + } + } + + // Use selector to choose from supported options + return c.requirementsSelector(version, supported), nil +} + +// CreatePaymentPayload creates a signed payment payload +// This is where the actual signing/wallet interaction happens +func (c *x402Client) CreatePaymentPayload(ctx context.Context, version int, requirements PaymentRequirements) (PaymentPayload, error) { + c.mu.RLock() + defer c.mu.RUnlock() + + // Validate requirements + if err := ValidatePaymentRequirements(requirements); err != nil { + return PaymentPayload{}, fmt.Errorf("invalid payment requirements: %w", err) + } + + versionSchemes, exists := c.schemes[version] + if !exists { + return PaymentPayload{}, fmt.Errorf("no schemes registered for x402 version %d", version) + } + + // Find the appropriate client + client := findByNetworkAndScheme(versionSchemes, requirements.Scheme, requirements.Network) + if client == nil { + return PaymentPayload{}, &PaymentError{ + Code: ErrCodeUnsupportedScheme, + Message: fmt.Sprintf("no client registered for scheme %s on network %s", requirements.Scheme, requirements.Network), + } + } + + // Create the payment payload using the mechanism-specific client + payload, err := client.CreatePaymentPayload(ctx, version, requirements) + if err != nil { + return PaymentPayload{}, fmt.Errorf("failed to create payment payload: %w", err) + } + + // Validate the created payload + if err := ValidatePaymentPayload(payload); err != nil { + return PaymentPayload{}, fmt.Errorf("invalid payment payload created: %w", err) + } + + return payload, nil +} + +// GetRegisteredSchemes returns a list of registered schemes for debugging +func (c *x402Client) GetRegisteredSchemes() map[int][]struct { + Network Network + Scheme string +} { + c.mu.RLock() + defer c.mu.RUnlock() + + result := make(map[int][]struct { + Network Network + Scheme string + }) + + for version, versionSchemes := range c.schemes { + for network, schemes := range versionSchemes { + for scheme := range schemes { + result[version] = append(result[version], struct { + Network Network + Scheme string + }{ + Network: network, + Scheme: scheme, + }) + } + } + } + + return result +} + +// CanPay checks if the client can pay with any of the given requirements +func (c *x402Client) CanPay(version int, requirements []PaymentRequirements) bool { + _, err := c.SelectPaymentRequirements(version, requirements) + return err == nil +} + +// CreatePaymentForRequired creates a payment for a PaymentRequired response +func (c *x402Client) CreatePaymentForRequired(ctx context.Context, required PaymentRequired) (PaymentPayload, error) { + // Select appropriate requirements + selected, err := c.SelectPaymentRequirements(required.X402Version, required.Accepts) + if err != nil { + return PaymentPayload{}, err + } + + // Create payment + return c.CreatePaymentPayload(ctx, required.X402Version, selected) +} diff --git a/go/client_test.go b/go/client_test.go new file mode 100644 index 000000000..ce6072f6e --- /dev/null +++ b/go/client_test.go @@ -0,0 +1,393 @@ +package x402 + +import ( + "context" + "errors" + "testing" +) + +// Mock client for testing +type mockSchemeNetworkClient struct { + scheme string + createPayload func(ctx context.Context, version int, requirements PaymentRequirements) (PaymentPayload, error) +} + +func (m *mockSchemeNetworkClient) Scheme() string { + return m.scheme +} + +func (m *mockSchemeNetworkClient) CreatePaymentPayload(ctx context.Context, version int, requirements PaymentRequirements) (PaymentPayload, error) { + if m.createPayload != nil { + return m.createPayload(ctx, version, requirements) + } + return PaymentPayload{ + X402Version: version, + Scheme: m.scheme, + Network: requirements.Network, + Payload: map[string]interface{}{ + "signature": "mock_signature", + "from": "0xmock", + }, + }, nil +} + +func TestNewx402Client(t *testing.T) { + client := Newx402Client() + if client == nil { + t.Fatal("Expected client to be created") + } + if client.schemes == nil { + t.Fatal("Expected schemes map to be initialized") + } + if client.requirementsSelector == nil { + t.Fatal("Expected default selector to be set") + } +} + +func TestClientRegisterScheme(t *testing.T) { + client := Newx402Client() + mockClient := &mockSchemeNetworkClient{scheme: "exact"} + + // Test v2 registration + client.RegisterScheme("eip155:1", mockClient) + + if len(client.schemes) != 1 { + t.Fatalf("Expected 1 version, got %d", len(client.schemes)) + } + if len(client.schemes[2]) != 1 { + t.Fatal("Expected 1 network for v2") + } + if client.schemes[2]["eip155:1"]["exact"] != mockClient { + t.Fatal("Expected mock client to be registered") + } + + // Test v1 registration + client.RegisterSchemeV1("eip155:1", mockClient) + if len(client.schemes) != 2 { + t.Fatalf("Expected 2 versions, got %d", len(client.schemes)) + } + if client.schemes[1]["eip155:1"]["exact"] != mockClient { + t.Fatal("Expected mock client to be registered for v1") + } +} + +func TestClientWithScheme(t *testing.T) { + mockClient := &mockSchemeNetworkClient{scheme: "exact"} + + client := Newx402Client( + WithScheme(2, "eip155:1", mockClient), + ) + + if client.schemes[2]["eip155:1"]["exact"] != mockClient { + t.Fatal("Expected mock client to be registered via option") + } +} + +func TestClientSelectPaymentRequirements(t *testing.T) { + client := Newx402Client() + mockClient := &mockSchemeNetworkClient{scheme: "exact"} + client.RegisterScheme("eip155:1", mockClient) + + requirements := []PaymentRequirements{ + { + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + }, + { + Scheme: "unsupported", + Network: "eip155:1", + Asset: "USDC", + Amount: "2000000", + PayTo: "0xrecipient", + }, + } + + // Should select the first supported requirement + selected, err := client.SelectPaymentRequirements(2, requirements) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if selected.Scheme != "exact" { + t.Fatalf("Expected 'exact' scheme, got %s", selected.Scheme) + } + if selected.Amount != "1000000" { + t.Fatalf("Expected amount '1000000', got %s", selected.Amount) + } + + // Test with no supported requirements + unsupportedReqs := []PaymentRequirements{ + { + Scheme: "unsupported", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + }, + } + + _, err = client.SelectPaymentRequirements(2, unsupportedReqs) + if err == nil { + t.Fatal("Expected error for unsupported requirements") + } + + var paymentErr *PaymentError + if !errors.As(err, &paymentErr) || paymentErr.Code != ErrCodeUnsupportedScheme { + t.Fatal("Expected UnsupportedScheme error") + } +} + +func TestClientSelectPaymentRequirementsWithCustomSelector(t *testing.T) { + // Custom selector that chooses the highest amount + customSelector := func(version int, requirements []PaymentRequirements) PaymentRequirements { + if len(requirements) == 0 { + panic("no requirements") + } + highest := requirements[0] + for _, req := range requirements[1:] { + if req.Amount > highest.Amount { + highest = req + } + } + return highest + } + + client := Newx402Client(WithPaymentSelector(customSelector)) + mockClient := &mockSchemeNetworkClient{scheme: "exact"} + client.RegisterScheme("eip155:1", mockClient) + + requirements := []PaymentRequirements{ + { + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + }, + { + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "2000000", + PayTo: "0xrecipient", + }, + } + + selected, err := client.SelectPaymentRequirements(2, requirements) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if selected.Amount != "2000000" { + t.Fatalf("Expected amount '2000000', got %s", selected.Amount) + } +} + +func TestClientCreatePaymentPayload(t *testing.T) { + ctx := context.Background() + client := Newx402Client() + + mockClient := &mockSchemeNetworkClient{ + scheme: "exact", + createPayload: func(ctx context.Context, version int, requirements PaymentRequirements) (PaymentPayload, error) { + return PaymentPayload{ + X402Version: version, + Scheme: "exact", + Network: requirements.Network, + Payload: map[string]interface{}{ + "signature": "test_sig", + "from": "0xsender", + }, + }, nil + }, + } + + client.RegisterScheme("eip155:1", mockClient) + + requirements := PaymentRequirements{ + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + } + + payload, err := client.CreatePaymentPayload(ctx, 2, requirements) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if payload.X402Version != 2 { + t.Fatalf("Expected version 2, got %d", payload.X402Version) + } + if payload.Scheme != "exact" { + t.Fatalf("Expected scheme 'exact', got %s", payload.Scheme) + } + if payload.Network != "eip155:1" { + t.Fatalf("Expected network 'eip155:1', got %s", payload.Network) + } + if payload.Payload == nil { + t.Fatal("Expected payload to be set") + } +} + +func TestClientCreatePaymentPayloadValidation(t *testing.T) { + ctx := context.Background() + client := Newx402Client() + + // Test with invalid requirements (missing scheme) + invalidReqs := PaymentRequirements{ + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + } + + _, err := client.CreatePaymentPayload(ctx, 2, invalidReqs) + if err == nil { + t.Fatal("Expected error for invalid requirements") + } +} + +func TestClientCreatePaymentPayloadNoScheme(t *testing.T) { + ctx := context.Background() + client := Newx402Client() + + // Register a different scheme so we get past the version check + mockClient := &mockSchemeNetworkClient{scheme: "different"} + client.RegisterScheme("eip155:1", mockClient) + + requirements := PaymentRequirements{ + Scheme: "unregistered", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + } + + _, err := client.CreatePaymentPayload(ctx, 2, requirements) + if err == nil { + t.Fatal("Expected error for unregistered scheme") + } + + var paymentErr *PaymentError + if !errors.As(err, &paymentErr) { + t.Fatalf("Expected PaymentError, got: %v (%T)", err, err) + } + if paymentErr.Code != ErrCodeUnsupportedScheme { + t.Fatalf("Expected UnsupportedScheme error code, got: %s", paymentErr.Code) + } +} + +func TestClientGetRegisteredSchemes(t *testing.T) { + client := Newx402Client() + mockClient1 := &mockSchemeNetworkClient{scheme: "exact"} + mockClient2 := &mockSchemeNetworkClient{scheme: "transfer"} + + client.RegisterScheme("eip155:1", mockClient1) + client.RegisterScheme("eip155:8453", mockClient2) + client.RegisterSchemeV1("eip155:1", mockClient1) + + schemes := client.GetRegisteredSchemes() + if len(schemes) != 2 { + t.Fatalf("Expected 2 versions, got %d", len(schemes)) + } + if len(schemes[2]) != 2 { + t.Fatalf("Expected 2 schemes for v2, got %d", len(schemes[2])) + } + if len(schemes[1]) != 1 { + t.Fatalf("Expected 1 scheme for v1, got %d", len(schemes[1])) + } +} + +func TestClientCanPay(t *testing.T) { + client := Newx402Client() + mockClient := &mockSchemeNetworkClient{scheme: "exact"} + client.RegisterScheme("eip155:1", mockClient) + + requirements := []PaymentRequirements{ + { + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + }, + } + + if !client.CanPay(2, requirements) { + t.Fatal("Expected client to be able to pay") + } + + unsupportedReqs := []PaymentRequirements{ + { + Scheme: "unsupported", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + }, + } + + if client.CanPay(2, unsupportedReqs) { + t.Fatal("Expected client to not be able to pay unsupported requirements") + } +} + +func TestClientCreatePaymentForRequired(t *testing.T) { + ctx := context.Background() + client := Newx402Client() + mockClient := &mockSchemeNetworkClient{scheme: "exact"} + client.RegisterScheme("eip155:1", mockClient) + + required := PaymentRequired{ + X402Version: 2, + Error: "Payment required", + Accepts: []PaymentRequirements{ + { + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + }, + }, + } + + payload, err := client.CreatePaymentForRequired(ctx, required) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if payload.X402Version != 2 { + t.Fatalf("Expected version 2, got %d", payload.X402Version) + } + if payload.Scheme != "exact" { + t.Fatalf("Expected scheme 'exact', got %s", payload.Scheme) + } +} + +func TestClientNetworkPatternMatching(t *testing.T) { + client := Newx402Client() + mockClient := &mockSchemeNetworkClient{scheme: "exact"} + + // Register with wildcard + client.RegisterScheme("eip155:*", mockClient) + + requirements := PaymentRequirements{ + Scheme: "exact", + Network: "eip155:8453", // Specific network + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + } + + // Should match the wildcard pattern + ctx := context.Background() + payload, err := client.CreatePaymentPayload(ctx, 2, requirements) + if err != nil { + t.Fatalf("Expected pattern match to work: %v", err) + } + if payload.Scheme != "exact" { + t.Fatal("Expected payload to be created with pattern match") + } +} diff --git a/go/constants.go b/go/constants.go new file mode 100644 index 000000000..2d5a74e03 --- /dev/null +++ b/go/constants.go @@ -0,0 +1,25 @@ +package x402 + +// Version constants +const ( + // Version is the SDK version + Version = "2.0.0" + + // ProtocolVersion is the current x402 protocol version + ProtocolVersion = 2 + + // ProtocolVersionV1 is the legacy x402 protocol version + ProtocolVersionV1 = 1 +) + +// Export the main types with uppercase names for external packages +type ( + // X402Client is the exported type for x402Client + X402Client = x402Client + + // X402ResourceService is the exported type for x402ResourceService + X402ResourceService = x402ResourceService + + // X402Facilitator is the exported type for x402Facilitator + X402Facilitator = x402Facilitator +) diff --git a/go/errors.go b/go/errors.go new file mode 100644 index 000000000..b3edb8674 --- /dev/null +++ b/go/errors.go @@ -0,0 +1,37 @@ +package x402 + +import "fmt" + +// PaymentError represents a payment-specific error +type PaymentError struct { + Code string `json:"code"` + Message string `json:"message"` + Details map[string]interface{} `json:"details,omitempty"` +} + +func (e *PaymentError) Error() string { + return fmt.Sprintf("%s: %s", e.Code, e.Message) +} + +// Common error codes +const ( + ErrCodeInvalidPayment = "invalid_payment" + ErrCodePaymentRequired = "payment_required" + ErrCodeInsufficientFunds = "insufficient_funds" + ErrCodeNetworkMismatch = "network_mismatch" + ErrCodeSchemeMismatch = "scheme_mismatch" + ErrCodeSignatureInvalid = "signature_invalid" + ErrCodePaymentExpired = "payment_expired" + ErrCodeSettlementFailed = "settlement_failed" + ErrCodeUnsupportedScheme = "unsupported_scheme" + ErrCodeUnsupportedNetwork = "unsupported_network" +) + +// NewPaymentError creates a new payment error +func NewPaymentError(code, message string, details map[string]interface{}) *PaymentError { + return &PaymentError{ + Code: code, + Message: message, + Details: details, + } +} diff --git a/go/facilitator.go b/go/facilitator.go new file mode 100644 index 000000000..a0ed4e7a7 --- /dev/null +++ b/go/facilitator.go @@ -0,0 +1,270 @@ +package x402 + +import ( + "context" + "fmt" + "sync" +) + +// x402Facilitator manages payment verification and settlement +// This is used by payment processors that execute on-chain transactions +type x402Facilitator struct { + mu sync.RWMutex + + // Nested map: version -> network -> scheme -> facilitator implementation + schemes map[int]map[Network]map[string]SchemeNetworkFacilitator + + // Extensions this facilitator supports (e.g., "bazaar", "sign_in_with_x") + extensions []string +} + +// Newx402Facilitator creates a new facilitator +func Newx402Facilitator() *x402Facilitator { + return &x402Facilitator{ + schemes: make(map[int]map[Network]map[string]SchemeNetworkFacilitator), + extensions: []string{}, + } +} + +// RegisterScheme registers a payment mechanism for protocol v2 +func (f *x402Facilitator) RegisterScheme(network Network, facilitator SchemeNetworkFacilitator) *x402Facilitator { + return f.registerScheme(ProtocolVersion, network, facilitator) +} + +// RegisterSchemeV1 registers a payment mechanism for protocol v1 +func (f *x402Facilitator) RegisterSchemeV1(network Network, facilitator SchemeNetworkFacilitator) *x402Facilitator { + return f.registerScheme(ProtocolVersionV1, network, facilitator) +} + +// registerScheme internal method to register schemes +func (f *x402Facilitator) registerScheme(version int, network Network, facilitator SchemeNetworkFacilitator) *x402Facilitator { + f.mu.Lock() + defer f.mu.Unlock() + + // Initialize nested maps if needed + if f.schemes[version] == nil { + f.schemes[version] = make(map[Network]map[string]SchemeNetworkFacilitator) + } + if f.schemes[version][network] == nil { + f.schemes[version][network] = make(map[string]SchemeNetworkFacilitator) + } + + // Register the facilitator for this scheme + f.schemes[version][network][facilitator.Scheme()] = facilitator + + return f +} + +// RegisterExtension registers a protocol extension +func (f *x402Facilitator) RegisterExtension(extension string) *x402Facilitator { + f.mu.Lock() + defer f.mu.Unlock() + + // Check if already registered + for _, ext := range f.extensions { + if ext == extension { + return f + } + } + + f.extensions = append(f.extensions, extension) + return f +} + +// Verify checks if a payment is valid without executing it +// This validates signatures, checks balances, etc. +func (f *x402Facilitator) Verify(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (VerifyResponse, error) { + f.mu.RLock() + defer f.mu.RUnlock() + + // Validate inputs + if err := ValidatePaymentPayload(payload); err != nil { + return VerifyResponse{ + IsValid: false, + InvalidReason: err.Error(), + }, err + } + + if err := ValidatePaymentRequirements(requirements); err != nil { + return VerifyResponse{ + IsValid: false, + InvalidReason: err.Error(), + }, err + } + + // Check version compatibility + versionSchemes, exists := f.schemes[payload.X402Version] + if !exists { + return VerifyResponse{ + IsValid: false, + InvalidReason: fmt.Sprintf("unsupported x402 version: %d", payload.X402Version), + }, &PaymentError{ + Code: ErrCodeInvalidPayment, + Message: fmt.Sprintf("x402 version %d not supported", payload.X402Version), + } + } + + // Find the appropriate facilitator + facilitator := findByNetworkAndScheme(versionSchemes, requirements.Scheme, requirements.Network) + if facilitator == nil { + return VerifyResponse{ + IsValid: false, + InvalidReason: fmt.Sprintf("unsupported scheme %s on network %s", requirements.Scheme, requirements.Network), + }, &PaymentError{ + Code: ErrCodeUnsupportedScheme, + Message: fmt.Sprintf("no facilitator for scheme %s on network %s", requirements.Scheme, requirements.Network), + } + } + + // Verify basic compatibility + if payload.Scheme != requirements.Scheme { + return VerifyResponse{ + IsValid: false, + InvalidReason: "scheme mismatch", + }, &PaymentError{ + Code: ErrCodeSchemeMismatch, + Message: fmt.Sprintf("payment scheme %s does not match requirement %s", payload.Scheme, requirements.Scheme), + } + } + + if !Network(payload.Network).Match(requirements.Network) { + return VerifyResponse{ + IsValid: false, + InvalidReason: "network mismatch", + }, &PaymentError{ + Code: ErrCodeNetworkMismatch, + Message: fmt.Sprintf("payment network %s does not match requirement %s", payload.Network, requirements.Network), + } + } + + // Delegate to mechanism-specific verification + return facilitator.Verify(ctx, payload, requirements) +} + +// Settle executes a payment on-chain +// This is where the actual blockchain transaction happens +func (f *x402Facilitator) Settle(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (SettleResponse, error) { + f.mu.RLock() + defer f.mu.RUnlock() + + // Check version compatibility + versionSchemes, exists := f.schemes[payload.X402Version] + if !exists { + return SettleResponse{ + Success: false, + ErrorReason: fmt.Sprintf("unsupported x402 version: %d", payload.X402Version), + Network: payload.Network, + }, &PaymentError{ + Code: ErrCodeInvalidPayment, + Message: fmt.Sprintf("x402 version %d not supported", payload.X402Version), + } + } + + // Find the appropriate facilitator + facilitator := findByNetworkAndScheme(versionSchemes, requirements.Scheme, requirements.Network) + if facilitator == nil { + return SettleResponse{ + Success: false, + ErrorReason: fmt.Sprintf("unsupported scheme %s on network %s", requirements.Scheme, requirements.Network), + Network: payload.Network, + }, &PaymentError{ + Code: ErrCodeUnsupportedScheme, + Message: fmt.Sprintf("no facilitator for scheme %s on network %s", requirements.Scheme, requirements.Network), + } + } + + // Always verify before settling + verifyResp, err := facilitator.Verify(ctx, payload, requirements) + if err != nil { + return SettleResponse{ + Success: false, + ErrorReason: fmt.Sprintf("verification failed: %v", err), + Network: payload.Network, + }, err + } + + if !verifyResp.IsValid { + return SettleResponse{ + Success: false, + ErrorReason: verifyResp.InvalidReason, + Payer: verifyResp.Payer, + Network: payload.Network, + }, &PaymentError{ + Code: ErrCodeInvalidPayment, + Message: verifyResp.InvalidReason, + } + } + + // Delegate to mechanism-specific settlement + return facilitator.Settle(ctx, payload, requirements) +} + +// GetSupported returns the payment kinds this facilitator supports +func (f *x402Facilitator) GetSupported() SupportedResponse { + f.mu.RLock() + defer f.mu.RUnlock() + + response := SupportedResponse{ + Kinds: []SupportedKind{}, + Extensions: f.extensions, + } + + // Build list of supported kinds + for version, versionSchemes := range f.schemes { + for network, schemes := range versionSchemes { + for scheme := range schemes { + response.Kinds = append(response.Kinds, SupportedKind{ + X402Version: version, + Scheme: scheme, + Network: network, + Extra: map[string]interface{}{}, + }) + } + } + } + + return response +} + +// CanHandle checks if the facilitator can handle a payment type +func (f *x402Facilitator) CanHandle(version int, network Network, scheme string) bool { + f.mu.RLock() + defer f.mu.RUnlock() + + versionSchemes, exists := f.schemes[version] + if !exists { + return false + } + + return findByNetworkAndScheme(versionSchemes, scheme, network) != nil +} + +// LocalFacilitatorClient wraps a local facilitator to implement FacilitatorClient +// This allows using a local facilitator in the same process as the service +type LocalFacilitatorClient struct { + facilitator *x402Facilitator + identifier string +} + +// NewLocalFacilitatorClient creates a facilitator client backed by a local facilitator +func NewLocalFacilitatorClient(facilitator *x402Facilitator) *LocalFacilitatorClient { + return &LocalFacilitatorClient{ + facilitator: facilitator, + identifier: "local", + } +} + +// Verify implements FacilitatorClient +func (c *LocalFacilitatorClient) Verify(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (VerifyResponse, error) { + return c.facilitator.Verify(ctx, payload, requirements) +} + +// Settle implements FacilitatorClient +func (c *LocalFacilitatorClient) Settle(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (SettleResponse, error) { + return c.facilitator.Settle(ctx, payload, requirements) +} + +// GetSupported implements FacilitatorClient +func (c *LocalFacilitatorClient) GetSupported(ctx context.Context) (SupportedResponse, error) { + return c.facilitator.GetSupported(), nil +} diff --git a/go/facilitator_test.go b/go/facilitator_test.go new file mode 100644 index 000000000..ce1e640b8 --- /dev/null +++ b/go/facilitator_test.go @@ -0,0 +1,519 @@ +package x402 + +import ( + "context" + "errors" + "testing" +) + +// Mock facilitator for testing +type mockSchemeNetworkFacilitator struct { + scheme string + verify func(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (VerifyResponse, error) + settle func(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (SettleResponse, error) +} + +func (m *mockSchemeNetworkFacilitator) Scheme() string { + return m.scheme +} + +func (m *mockSchemeNetworkFacilitator) Verify(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (VerifyResponse, error) { + if m.verify != nil { + return m.verify(ctx, payload, requirements) + } + return VerifyResponse{ + IsValid: true, + Payer: "0xmockpayer", + }, nil +} + +func (m *mockSchemeNetworkFacilitator) Settle(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (SettleResponse, error) { + if m.settle != nil { + return m.settle(ctx, payload, requirements) + } + return SettleResponse{ + Success: true, + Transaction: "0xmocktx", + Payer: "0xmockpayer", + Network: payload.Network, + }, nil +} + +func TestNewx402Facilitator(t *testing.T) { + facilitator := Newx402Facilitator() + if facilitator == nil { + t.Fatal("Expected facilitator to be created") + } + if facilitator.schemes == nil { + t.Fatal("Expected schemes map to be initialized") + } + if facilitator.extensions == nil { + t.Fatal("Expected extensions slice to be initialized") + } +} + +func TestFacilitatorRegisterScheme(t *testing.T) { + facilitator := Newx402Facilitator() + mockFacilitator := &mockSchemeNetworkFacilitator{scheme: "exact"} + + // Test v2 registration + facilitator.RegisterScheme("eip155:1", mockFacilitator) + + if len(facilitator.schemes) != 1 { + t.Fatalf("Expected 1 version, got %d", len(facilitator.schemes)) + } + if len(facilitator.schemes[2]) != 1 { + t.Fatal("Expected 1 network for v2") + } + if facilitator.schemes[2]["eip155:1"]["exact"] != mockFacilitator { + t.Fatal("Expected mock facilitator to be registered") + } + + // Test v1 registration + facilitator.RegisterSchemeV1("eip155:1", mockFacilitator) + if len(facilitator.schemes) != 2 { + t.Fatalf("Expected 2 versions, got %d", len(facilitator.schemes)) + } + if facilitator.schemes[1]["eip155:1"]["exact"] != mockFacilitator { + t.Fatal("Expected mock facilitator to be registered for v1") + } +} + +func TestFacilitatorRegisterExtension(t *testing.T) { + facilitator := Newx402Facilitator() + + facilitator.RegisterExtension("bazaar") + if len(facilitator.extensions) != 1 { + t.Fatal("Expected 1 extension") + } + if facilitator.extensions[0] != "bazaar" { + t.Fatal("Expected 'bazaar' extension") + } + + // Test duplicate registration (should not add twice) + facilitator.RegisterExtension("bazaar") + if len(facilitator.extensions) != 1 { + t.Fatal("Expected extension to not be duplicated") + } + + facilitator.RegisterExtension("sign_in_with_x") + if len(facilitator.extensions) != 2 { + t.Fatal("Expected 2 extensions") + } +} + +func TestFacilitatorVerify(t *testing.T) { + ctx := context.Background() + facilitator := Newx402Facilitator() + + mockFacilitator := &mockSchemeNetworkFacilitator{ + scheme: "exact", + verify: func(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (VerifyResponse, error) { + if payload.Scheme != requirements.Scheme { + return VerifyResponse{ + IsValid: false, + InvalidReason: "scheme mismatch", + }, nil + } + return VerifyResponse{ + IsValid: true, + Payer: "0xverifiedpayer", + }, nil + }, + } + + facilitator.RegisterScheme("eip155:1", mockFacilitator) + + payload := PaymentPayload{ + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + Payload: map[string]interface{}{ + "signature": "test", + }, + } + + requirements := PaymentRequirements{ + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + } + + response, err := facilitator.Verify(ctx, payload, requirements) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if !response.IsValid { + t.Fatal("Expected valid verification") + } + if response.Payer != "0xverifiedpayer" { + t.Fatalf("Expected payer '0xverifiedpayer', got %s", response.Payer) + } +} + +func TestFacilitatorVerifyValidation(t *testing.T) { + ctx := context.Background() + facilitator := Newx402Facilitator() + mockFacilitator := &mockSchemeNetworkFacilitator{scheme: "exact"} + facilitator.RegisterScheme("eip155:1", mockFacilitator) + + // Test invalid payload (missing scheme) + invalidPayload := PaymentPayload{ + X402Version: 2, + Network: "eip155:1", + Payload: map[string]interface{}{}, + } + + requirements := PaymentRequirements{ + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + } + + response, err := facilitator.Verify(ctx, invalidPayload, requirements) + if err == nil { + t.Fatal("Expected error for invalid payload") + } + if response.IsValid { + t.Fatal("Expected invalid response") + } + + // Test invalid requirements + validPayload := PaymentPayload{ + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + Payload: map[string]interface{}{}, + } + + invalidReqs := PaymentRequirements{ + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + } + + response, err = facilitator.Verify(ctx, validPayload, invalidReqs) + if err == nil { + t.Fatal("Expected error for invalid requirements") + } + if response.IsValid { + t.Fatal("Expected invalid response") + } +} + +func TestFacilitatorVerifySchemeMismatch(t *testing.T) { + ctx := context.Background() + facilitator := Newx402Facilitator() + mockFacilitator := &mockSchemeNetworkFacilitator{scheme: "exact"} + facilitator.RegisterScheme("eip155:1", mockFacilitator) + + payload := PaymentPayload{ + X402Version: 2, + Scheme: "transfer", // Different scheme + Network: "eip155:1", + Payload: map[string]interface{}{}, + } + + requirements := PaymentRequirements{ + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + } + + response, err := facilitator.Verify(ctx, payload, requirements) + if err == nil { + t.Fatal("Expected error for scheme mismatch") + } + + var paymentErr *PaymentError + if !errors.As(err, &paymentErr) || paymentErr.Code != ErrCodeSchemeMismatch { + t.Fatal("Expected SchemeMismatch error") + } + if response.IsValid { + t.Fatal("Expected invalid response") + } +} + +func TestFacilitatorVerifyNetworkMismatch(t *testing.T) { + ctx := context.Background() + facilitator := Newx402Facilitator() + mockFacilitator := &mockSchemeNetworkFacilitator{scheme: "exact"} + facilitator.RegisterScheme("eip155:1", mockFacilitator) + + payload := PaymentPayload{ + X402Version: 2, + Scheme: "exact", + Network: "eip155:8453", // Different network + Payload: map[string]interface{}{}, + } + + requirements := PaymentRequirements{ + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + } + + response, err := facilitator.Verify(ctx, payload, requirements) + if err == nil { + t.Fatal("Expected error for network mismatch") + } + + var paymentErr *PaymentError + if !errors.As(err, &paymentErr) || paymentErr.Code != ErrCodeNetworkMismatch { + t.Fatal("Expected NetworkMismatch error") + } + if response.IsValid { + t.Fatal("Expected invalid response") + } +} + +func TestFacilitatorSettle(t *testing.T) { + ctx := context.Background() + facilitator := Newx402Facilitator() + + mockFacilitator := &mockSchemeNetworkFacilitator{ + scheme: "exact", + settle: func(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (SettleResponse, error) { + return SettleResponse{ + Success: true, + Transaction: "0xsettledtx", + Payer: "0xpayer", + Network: payload.Network, + }, nil + }, + } + + facilitator.RegisterScheme("eip155:1", mockFacilitator) + + payload := PaymentPayload{ + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + Payload: map[string]interface{}{ + "signature": "test", + }, + } + + requirements := PaymentRequirements{ + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + } + + response, err := facilitator.Settle(ctx, payload, requirements) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if !response.Success { + t.Fatal("Expected successful settlement") + } + if response.Transaction != "0xsettledtx" { + t.Fatalf("Expected transaction '0xsettledtx', got %s", response.Transaction) + } +} + +func TestFacilitatorSettleVerifiesFirst(t *testing.T) { + ctx := context.Background() + facilitator := Newx402Facilitator() + + verifyCallCount := 0 + mockFacilitator := &mockSchemeNetworkFacilitator{ + scheme: "exact", + verify: func(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (VerifyResponse, error) { + verifyCallCount++ + return VerifyResponse{ + IsValid: false, + InvalidReason: "invalid signature", + }, nil + }, + } + + facilitator.RegisterScheme("eip155:1", mockFacilitator) + + payload := PaymentPayload{ + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + Payload: map[string]interface{}{}, + } + + requirements := PaymentRequirements{ + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + } + + response, err := facilitator.Settle(ctx, payload, requirements) + if err == nil { + t.Fatal("Expected error for invalid payment") + } + if response.Success { + t.Fatal("Expected failed settlement") + } + if verifyCallCount != 1 { + t.Fatal("Expected verify to be called before settle") + } +} + +func TestFacilitatorGetSupported(t *testing.T) { + facilitator := Newx402Facilitator() + + mockFacilitator1 := &mockSchemeNetworkFacilitator{scheme: "exact"} + mockFacilitator2 := &mockSchemeNetworkFacilitator{scheme: "transfer"} + + facilitator.RegisterScheme("eip155:1", mockFacilitator1) + facilitator.RegisterScheme("eip155:8453", mockFacilitator2) + facilitator.RegisterSchemeV1("eip155:1", mockFacilitator1) + facilitator.RegisterExtension("bazaar") + + supported := facilitator.GetSupported() + + if len(supported.Kinds) != 3 { + t.Fatalf("Expected 3 supported kinds, got %d", len(supported.Kinds)) + } + if len(supported.Extensions) != 1 { + t.Fatalf("Expected 1 extension, got %d", len(supported.Extensions)) + } + if supported.Extensions[0] != "bazaar" { + t.Fatal("Expected 'bazaar' extension") + } + + // Verify each kind + foundV2Exact := false + foundV2Transfer := false + foundV1Exact := false + + for _, kind := range supported.Kinds { + if kind.X402Version == 2 && kind.Scheme == "exact" && kind.Network == "eip155:1" { + foundV2Exact = true + } + if kind.X402Version == 2 && kind.Scheme == "transfer" && kind.Network == "eip155:8453" { + foundV2Transfer = true + } + if kind.X402Version == 1 && kind.Scheme == "exact" && kind.Network == "eip155:1" { + foundV1Exact = true + } + } + + if !foundV2Exact || !foundV2Transfer || !foundV1Exact { + t.Fatal("Expected all registered schemes to be in supported kinds") + } +} + +func TestFacilitatorCanHandle(t *testing.T) { + facilitator := Newx402Facilitator() + mockFacilitator := &mockSchemeNetworkFacilitator{scheme: "exact"} + facilitator.RegisterScheme("eip155:1", mockFacilitator) + + if !facilitator.CanHandle(2, "eip155:1", "exact") { + t.Fatal("Expected facilitator to handle registered scheme") + } + + if facilitator.CanHandle(2, "eip155:1", "transfer") { + t.Fatal("Expected facilitator to not handle unregistered scheme") + } + + if facilitator.CanHandle(1, "eip155:1", "exact") { + t.Fatal("Expected facilitator to not handle unregistered version") + } +} + +func TestLocalFacilitatorClient(t *testing.T) { + ctx := context.Background() + facilitator := Newx402Facilitator() + mockFacilitator := &mockSchemeNetworkFacilitator{scheme: "exact"} + facilitator.RegisterScheme("eip155:1", mockFacilitator) + + client := NewLocalFacilitatorClient(facilitator) + if client.identifier != "local" { + t.Fatal("Expected 'local' identifier") + } + + // Test Verify + payload := PaymentPayload{ + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + Payload: map[string]interface{}{}, + } + + requirements := PaymentRequirements{ + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + } + + verifyResp, err := client.Verify(ctx, payload, requirements) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if !verifyResp.IsValid { + t.Fatal("Expected valid verification") + } + + // Test Settle + settleResp, err := client.Settle(ctx, payload, requirements) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if !settleResp.Success { + t.Fatal("Expected successful settlement") + } + + // Test GetSupported + supportedResp, err := client.GetSupported(ctx) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if len(supportedResp.Kinds) != 1 { + t.Fatal("Expected 1 supported kind") + } +} + +func TestFacilitatorNetworkPatternMatching(t *testing.T) { + ctx := context.Background() + facilitator := Newx402Facilitator() + mockFacilitator := &mockSchemeNetworkFacilitator{scheme: "exact"} + + // Register with wildcard + facilitator.RegisterScheme("eip155:*", mockFacilitator) + + payload := PaymentPayload{ + X402Version: 2, + Scheme: "exact", + Network: "eip155:8453", // Specific network + Payload: map[string]interface{}{}, + } + + requirements := PaymentRequirements{ + Scheme: "exact", + Network: "eip155:8453", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + } + + // Should match the wildcard pattern + response, err := facilitator.Verify(ctx, payload, requirements) + if err != nil { + t.Fatalf("Expected pattern match to work: %v", err) + } + if !response.IsValid { + t.Fatal("Expected valid verification with pattern match") + } +} diff --git a/go/go.mod b/go/go.mod index 67dee8d4b..6ff6ab659 100644 --- a/go/go.mod +++ b/go/go.mod @@ -1,45 +1,51 @@ -module github.com/coinbase/x402/go +module github.com/coinbase/x402-go/v2 -go 1.23.3 +go 1.23.0 + +toolchain go1.24.1 require ( - github.com/coinbase/cdp-sdk/go v0.0.0-20250506223104-85d38372d771 - github.com/gin-gonic/gin v1.10.0 - github.com/joho/godotenv v1.5.1 - github.com/stretchr/testify v1.10.0 + github.com/ethereum/go-ethereum v1.13.0 + github.com/stretchr/testify v1.11.1 ) require ( - github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect - github.com/bytedance/sonic v1.13.2 // indirect - github.com/bytedance/sonic/loader v0.2.4 // indirect - github.com/cloudwego/base64x v0.1.5 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect + github.com/bytedance/sonic v1.14.0 // indirect + github.com/bytedance/sonic/loader v0.3.0 // indirect + github.com/cloudwego/base64x v0.1.6 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect github.com/gabriel-vasile/mimetype v1.4.8 // indirect - github.com/gin-contrib/sse v1.0.0 // indirect + github.com/gin-contrib/sse v1.1.0 // indirect + github.com/gin-gonic/gin v1.11.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.26.0 // indirect - github.com/goccy/go-json v0.10.5 // indirect - github.com/golang-jwt/jwt/v5 v5.2.2 // indirect - github.com/google/uuid v1.5.0 // indirect + github.com/go-playground/validator/v10 v10.27.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/goccy/go-yaml v1.18.0 // indirect + github.com/holiman/uint256 v1.2.4 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.10 // indirect - github.com/kr/text v0.2.0 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/oapi-codegen/runtime v1.1.1 // indirect - github.com/pelletier/go-toml/v2 v2.2.3 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/quic-go/qpack v0.5.1 // indirect + github.com/quic-go/quic-go v0.54.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.12 // indirect - golang.org/x/arch v0.15.0 // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/net v0.38.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect - google.golang.org/protobuf v1.36.6 // indirect + github.com/ugorji/go/codec v1.3.0 // indirect + go.uber.org/mock v0.5.0 // indirect + golang.org/x/arch v0.20.0 // indirect + golang.org/x/crypto v0.40.0 // indirect + golang.org/x/mod v0.25.0 // indirect + golang.org/x/net v0.42.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.35.0 // indirect + golang.org/x/text v0.27.0 // indirect + golang.org/x/tools v0.34.0 // indirect + google.golang.org/protobuf v1.36.9 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go/go.sum b/go/go.sum index 32422017a..a368068c9 100644 --- a/go/go.sum +++ b/go/go.sum @@ -1,110 +1,85 @@ -github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= -github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= -github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= -github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= -github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ= -github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= -github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= -github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= -github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= -github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= -github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= -github.com/coinbase/cdp-sdk/go v0.0.0-20250506223104-85d38372d771 h1:zFdgvx+jMCTkrOUTUD2Xmpk4vSusnpGqE90Gl37+WLQ= -github.com/coinbase/cdp-sdk/go v0.0.0-20250506223104-85d38372d771/go.mod h1:7SCUyseVQvmT158f23xvVghYF7dYxypj0sw+558F+7g= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= +github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ= +github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA= +github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= +github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= +github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/ethereum/go-ethereum v1.13.0/go.mod h1:0TDsBNJ7j8jR01vKpk4j2zfVKyAbQuKzy6wLwb5ZMuU= github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= -github.com/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E= -github.com/gin-contrib/sse v1.0.0/go.mod h1:zNuFdwarAygJBht0NTKiSi3jRf6RbqeILZ9Sp6Slhe0= -github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= -github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= -github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= -github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= +github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= +github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k= -github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= -github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= -github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= -github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= -github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= +github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= +github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= -github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= -github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= -github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro= -github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= -github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= -github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= +github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= +github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= +github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg= +github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= -github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -golang.org/x/arch v0.15.0 h1:QtOrQd0bTUnhNVNndMpLHNWrDmYzZ2KDqSrEymqInZw= -golang.org/x/arch v0.15.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= +github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= +golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c= +golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= +golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= +golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= +golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo= +golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= +google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= +google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= diff --git a/go/http/GIN.md b/go/http/GIN.md new file mode 100644 index 000000000..234510577 --- /dev/null +++ b/go/http/GIN.md @@ -0,0 +1,609 @@ +# GIN - Gin Framework Middleware for x402 + +This package provides Gin framework middleware for the x402 payment protocol, enabling easy integration with Gin-based APIs. + +```go +package gin + +import ( + "bytes" + "context" + "fmt" + "io" + "net/http" + "strings" + "sync" + + "github.com/gin-gonic/gin" + x402 "github.com/coinbase/x402-go/v2" + x402http "github.com/coinbase/x402-go/v2/http" +) + +// ============================================================================ +// Gin Adapter Implementation +// ============================================================================ + +// GinAdapter implements HTTPAdapter for Gin framework +type GinAdapter struct { + ctx *gin.Context +} + +// NewGinAdapter creates a new Gin adapter +func NewGinAdapter(ctx *gin.Context) *GinAdapter { + return &GinAdapter{ctx: ctx} +} + +// GetHeader gets a request header +func (a *GinAdapter) GetHeader(name string) string { + return a.ctx.GetHeader(name) +} + +// GetMethod gets the HTTP method +func (a *GinAdapter) GetMethod() string { + return a.ctx.Request.Method +} + +// GetPath gets the request path +func (a *GinAdapter) GetPath() string { + return a.ctx.Request.URL.Path +} + +// GetURL gets the full request URL +func (a *GinAdapter) GetURL() string { + scheme := "http" + if a.ctx.Request.TLS != nil { + scheme = "https" + } + host := a.ctx.Request.Host + if host == "" { + host = a.ctx.GetHeader("Host") + } + return fmt.Sprintf("%s://%s%s", scheme, host, a.ctx.Request.URL.Path) +} + +// GetAcceptHeader gets the Accept header +func (a *GinAdapter) GetAcceptHeader() string { + return a.ctx.GetHeader("Accept") +} + +// GetUserAgent gets the User-Agent header +func (a *GinAdapter) GetUserAgent() string { + return a.ctx.GetHeader("User-Agent") +} + +// ============================================================================ +// Middleware Configuration +// ============================================================================ + +// MiddlewareConfig configures the payment middleware +type MiddlewareConfig struct { + // Routes configuration + Routes x402http.RoutesConfig + + // Facilitator client(s) + FacilitatorClients []x402.FacilitatorClient + + // Scheme registrations + Schemes []SchemeRegistration + + // Paywall configuration + PaywallConfig *x402http.PaywallConfig + + // Initialize on startup + InitializeOnStart bool + + // Custom error handler + ErrorHandler func(*gin.Context, error) + + // Custom settlement handler + SettlementHandler func(*gin.Context, x402.SettleResponse) + + // Context timeout for payment operations + Timeout time.Duration +} + +// SchemeRegistration registers a scheme with the service +type SchemeRegistration struct { + Network x402.Network + Service x402.SchemeNetworkService +} + +// MiddlewareOption configures the middleware +type MiddlewareOption func(*MiddlewareConfig) + +// WithFacilitatorClient adds a facilitator client +func WithFacilitatorClient(client x402.FacilitatorClient) MiddlewareOption { + return func(c *MiddlewareConfig) { + c.FacilitatorClients = append(c.FacilitatorClients, client) + } +} + +// WithScheme registers a scheme service +func WithScheme(network x402.Network, service x402.SchemeNetworkService) MiddlewareOption { + return func(c *MiddlewareConfig) { + c.Schemes = append(c.Schemes, SchemeRegistration{ + Network: network, + Service: service, + }) + } +} + +// WithPaywallConfig sets the paywall configuration +func WithPaywallConfig(config *x402http.PaywallConfig) MiddlewareOption { + return func(c *MiddlewareConfig) { + c.PaywallConfig = config + } +} + +// WithInitializeOnStart sets whether to initialize on startup +func WithInitializeOnStart(initialize bool) MiddlewareOption { + return func(c *MiddlewareConfig) { + c.InitializeOnStart = initialize + } +} + +// WithErrorHandler sets a custom error handler +func WithErrorHandler(handler func(*gin.Context, error)) MiddlewareOption { + return func(c *MiddlewareConfig) { + c.ErrorHandler = handler + } +} + +// WithSettlementHandler sets a custom settlement handler +func WithSettlementHandler(handler func(*gin.Context, x402.SettleResponse)) MiddlewareOption { + return func(c *MiddlewareConfig) { + c.SettlementHandler = handler + } +} + +// WithTimeout sets the context timeout for payment operations +func WithTimeout(timeout time.Duration) MiddlewareOption { + return func(c *MiddlewareConfig) { + c.Timeout = timeout + } +} + +// ============================================================================ +// Payment Middleware +// ============================================================================ + +// PaymentMiddleware creates Gin middleware for x402 payment handling +func PaymentMiddleware(routes x402http.RoutesConfig, opts ...MiddlewareOption) gin.HandlerFunc { + config := &MiddlewareConfig{ + Routes: routes, + FacilitatorClients: []x402.FacilitatorClient{}, + Schemes: []SchemeRegistration{}, + InitializeOnStart: true, + Timeout: 30 * time.Second, + } + + // Apply options + for _, opt := range opts { + opt(config) + } + + // Create service options + serviceOpts := []x402.ResourceServiceOption{} + for _, client := range config.FacilitatorClients { + serviceOpts = append(serviceOpts, x402.WithFacilitatorClient(client)) + } + + // Create HTTP service + service := x402http.NewHTTPResourceService(config.Routes, serviceOpts...) + + // Register schemes + for _, scheme := range config.Schemes { + service.RegisterScheme(scheme.Network, scheme.Service) + } + + // Initialize if requested + if config.InitializeOnStart { + ctx, cancel := context.WithTimeout(context.Background(), config.Timeout) + defer cancel() + + if err := service.Initialize(ctx); err != nil { + // Log initialization error but don't fail - facilitator might come online later + fmt.Printf("Warning: failed to initialize x402 service: %v\n", err) + } + } + + // Create middleware handler + return func(c *gin.Context) { + // Create context with timeout + ctx, cancel := context.WithTimeout(c.Request.Context(), config.Timeout) + defer cancel() + + // Create adapter and request context + adapter := NewGinAdapter(c) + reqCtx := x402http.HTTPRequestContext{ + Adapter: adapter, + Path: c.Request.URL.Path, + Method: c.Request.Method, + } + + // Process HTTP request + result := service.ProcessHTTPRequest(ctx, reqCtx, config.PaywallConfig) + + // Handle result + switch result.Type { + case x402http.ResultNoPaymentRequired: + // No payment required, continue to next handler + c.Next() + + case x402http.ResultPaymentError: + // Payment required but not provided or invalid + handlePaymentError(c, result.Response, config) + + case x402http.ResultPaymentVerified: + // Payment verified, continue with settlement handling + handlePaymentVerified(c, service, ctx, result, config) + } + } +} + +// handlePaymentError handles payment error responses +func handlePaymentError(c *gin.Context, response *x402http.HTTPResponseInstructions, config *MiddlewareConfig) { + // Set status + c.Status(response.Status) + + // Set headers + for key, value := range response.Headers { + c.Header(key, value) + } + + // Send response body + if response.IsHTML { + c.Data(response.Status, "text/html; charset=utf-8", []byte(response.Body.(string))) + } else { + c.JSON(response.Status, response.Body) + } + + // Abort to prevent further handlers + c.Abort() +} + +// handlePaymentVerified handles verified payments with settlement +func handlePaymentVerified(c *gin.Context, service *x402http.HTTPResourceService, ctx context.Context, result x402http.HTTPProcessResult, config *MiddlewareConfig) { + // Capture response for settlement + writer := &responseCapture{ + ResponseWriter: c.Writer, + body: &bytes.Buffer{}, + statusCode: http.StatusOK, + } + c.Writer = writer + + // Continue to protected handler + c.Next() + + // Check if aborted + if c.IsAborted() { + return + } + + // Restore original writer + c.Writer = writer.ResponseWriter + + // Don't settle if response failed + if writer.statusCode >= 400 { + // Write captured response + c.Writer.WriteHeader(writer.statusCode) + c.Writer.Write(writer.body.Bytes()) + return + } + + // Process settlement + settlementHeaders, err := service.ProcessSettlement( + ctx, + *result.PaymentPayload, + *result.PaymentRequirements, + writer.statusCode, + ) + + if err != nil { + // Settlement failed + if config.ErrorHandler != nil { + config.ErrorHandler(c, fmt.Errorf("settlement failed: %w", err)) + } else { + // Default error handling + c.JSON(http.StatusInternalServerError, gin.H{ + "error": "Settlement failed", + "details": err.Error(), + }) + } + return + } + + // Add settlement headers + if settlementHeaders != nil { + for key, value := range settlementHeaders { + c.Header(key, value) + } + + // Call settlement handler if configured + if config.SettlementHandler != nil && settlementHeaders["PAYMENT-RESPONSE"] != "" { + // Decode settlement response + settleResponse, _ := x402http.DecodePaymentResponseHeader(settlementHeaders["PAYMENT-RESPONSE"]) + config.SettlementHandler(c, settleResponse) + } + } + + // Write captured response + c.Writer.WriteHeader(writer.statusCode) + c.Writer.Write(writer.body.Bytes()) +} + +// ============================================================================ +// Response Capture +// ============================================================================ + +// responseCapture captures the response for settlement processing +type responseCapture struct { + gin.ResponseWriter + body *bytes.Buffer + statusCode int + written bool + mu sync.Mutex +} + +// WriteHeader captures the status code +func (w *responseCapture) WriteHeader(code int) { + w.mu.Lock() + defer w.mu.Unlock() + + if !w.written { + w.statusCode = code + w.written = true + } +} + +// Write captures the response body +func (w *responseCapture) Write(data []byte) (int, error) { + w.mu.Lock() + defer w.mu.Unlock() + + if !w.written { + w.WriteHeader(http.StatusOK) + } + return w.body.Write(data) +} + +// WriteString captures string responses +func (w *responseCapture) WriteString(s string) (int, error) { + return w.Write([]byte(s)) +} + +// ============================================================================ +// Convenience Functions +// ============================================================================ + +// SimplePaymentMiddleware creates middleware with common defaults +func SimplePaymentMiddleware(payTo string, price string, network x402.Network, facilitatorURL string) gin.HandlerFunc { + // Create facilitator client + facilitator := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{ + URL: facilitatorURL, + }) + + // Create routes for all endpoints + routes := x402http.RoutesConfig{ + "*": x402http.RouteConfig{ + Scheme: "exact", + PayTo: payTo, + Price: price, + Network: network, + }, + } + + return PaymentMiddleware(routes, + WithFacilitatorClient(facilitator), + WithInitializeOnStart(true), + ) +} + +// RouteSpecificMiddleware creates middleware with per-route configuration +func RouteSpecificMiddleware(facilitatorURL string) gin.HandlerFunc { + facilitator := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{ + URL: facilitatorURL, + }) + + routes := x402http.RoutesConfig{ + "GET /api/data": { + Scheme: "exact", + PayTo: "0x...", + Price: "$0.10", + Network: "eip155:8453", + Description: "API data access", + }, + "POST /api/compute": { + Scheme: "exact", + PayTo: "0x...", + Price: "$1.00", + Network: "eip155:8453", + Description: "Compute operation", + }, + } + + return PaymentMiddleware(routes, + WithFacilitatorClient(facilitator), + ) +} +``` + +## Usage Examples + +### Basic Setup +```go +package main + +import ( + "github.com/gin-gonic/gin" + x402gin "github.com/coinbase/x402-go/v2/http/gin" + "github.com/coinbase/x402-go/v2/mechanisms/evm" +) + +func main() { + r := gin.Default() + + // Simple middleware for all routes + r.Use(x402gin.SimplePaymentMiddleware( + "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb9", // payTo + "$0.10", // price + "eip155:8453", // network (Base) + "https://facilitator.x402.org", // facilitator URL + )) + + // Protected endpoint + r.GET("/api/data", func(c *gin.Context) { + c.JSON(200, gin.H{ + "data": "This is protected data", + }) + }) + + r.Run(":8080") +} +``` + +### Advanced Configuration +```go +func main() { + r := gin.Default() + + // Configure routes + routes := x402http.RoutesConfig{ + "GET /api/premium": { + Scheme: "exact", + PayTo: "0x...", + Price: "$1.00", + Network: "eip155:8453", + Description: "Premium API access", + MimeType: "application/json", + }, + "POST /api/compute": { + Scheme: "exact", + PayTo: "0x...", + Price: "$5.00", + Network: "eip155:8453", + }, + } + + // Create facilitator client + facilitator := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{ + URL: "https://facilitator.example.com", + AuthProvider: x402http.NewStaticAuthProvider("api-key"), + }) + + // Configure paywall + paywallConfig := &x402http.PaywallConfig{ + AppName: "My API", + AppLogo: "/static/logo.png", + CDPClientKey: "your-cdp-key", + Testnet: false, + } + + // Add middleware + r.Use(x402gin.PaymentMiddleware(routes, + x402gin.WithFacilitatorClient(facilitator), + x402gin.WithScheme("eip155:8453", evm.NewExactService()), + x402gin.WithPaywallConfig(paywallConfig), + x402gin.WithErrorHandler(func(c *gin.Context, err error) { + // Custom error handling + c.JSON(500, gin.H{"error": err.Error()}) + }), + x402gin.WithSettlementHandler(func(c *gin.Context, response x402.SettleResponse) { + // Log successful settlements + log.Printf("Payment settled: tx=%s payer=%s", response.Transaction, response.Payer) + }), + )) + + // Protected routes + r.GET("/api/premium", premiumHandler) + r.POST("/api/compute", computeHandler) + + r.Run(":8080") +} +``` + +### Group-Specific Middleware +```go +func main() { + r := gin.Default() + + // Public routes (no payment) + public := r.Group("/public") + public.GET("/info", infoHandler) + + // Paid API routes + api := r.Group("/api") + api.Use(x402gin.PaymentMiddleware( + x402http.RoutesConfig{ + "*": { + Scheme: "exact", + PayTo: "0x...", + Price: "$0.01", + Network: "eip155:8453", + }, + }, + x402gin.WithFacilitatorClient(facilitator), + )) + + api.GET("/data", dataHandler) + api.POST("/action", actionHandler) + + // Premium routes with higher prices + premium := r.Group("/premium") + premium.Use(x402gin.PaymentMiddleware( + x402http.RoutesConfig{ + "*": { + Scheme: "exact", + PayTo: "0x...", + Price: "$1.00", + Network: "eip155:8453", + }, + }, + x402gin.WithFacilitatorClient(facilitator), + )) + + premium.GET("/exclusive", exclusiveHandler) + + r.Run(":8080") +} +``` + +### Testing with Local Facilitator +```go +func main() { + // Create local facilitator for testing + facilitator := x402.NewFacilitator() + facilitator.RegisterScheme("eip155:8453", evm.NewExactFacilitator(signer)) + + localClient := x402.NewLocalFacilitatorClient(facilitator) + + r := gin.Default() + r.Use(x402gin.PaymentMiddleware(routes, + x402gin.WithFacilitatorClient(localClient), + )) + + r.Run(":8080") +} +``` + +## Key Features + +1. **Route Pattern Matching**: Supports wildcards and specific route patterns +2. **Response Capture**: Intercepts responses for settlement processing +3. **Browser Support**: Automatic paywall HTML for browser requests +4. **Error Handling**: Customizable error handlers +5. **Settlement Callbacks**: Optional callbacks for successful settlements +6. **Multiple Facilitators**: Support for fallback facilitators +7. **Scheme Registration**: Register custom payment schemes +8. **Context Timeouts**: Configurable timeouts for payment operations + +## Migration from Legacy Middleware + +| Legacy | New | +|--------|-----| +| `PaymentMiddleware(amount, address, opts...)` | `PaymentMiddleware(routes, opts...)` | +| `WithDescription()` | Part of `RouteConfig` | +| `WithTestnet()` | Network specified in route (e.g., "eip155:84532") | +| `WithFacilitatorConfig()` | `WithFacilitatorClient()` | +| Fixed to v1 | Supports v1 and v2 | +| Single price for all routes | Per-route pricing | diff --git a/go/http/client.go b/go/http/client.go new file mode 100644 index 000000000..bd4b59e72 --- /dev/null +++ b/go/http/client.go @@ -0,0 +1,330 @@ +package http + +import ( + "context" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + "sync" + + x402 "github.com/coinbase/x402-go/v2" +) + +// ============================================================================ +// x402HTTPClient - HTTP-aware payment client +// ============================================================================ + +// x402HTTPClient extends x402Client with HTTP-specific payment handling +type x402HTTPClient struct { + *x402.X402Client +} + +// Newx402HTTPClient creates a new HTTP-aware x402 client +func Newx402HTTPClient(opts ...x402.ClientOption) *x402HTTPClient { + return &x402HTTPClient{ + X402Client: x402.Newx402Client(opts...), + } +} + +// ============================================================================ +// Header Encoding/Decoding +// ============================================================================ + +// EncodePaymentSignatureHeader encodes a payment payload into HTTP headers +// Returns appropriate headers based on protocol version +func (c *x402HTTPClient) EncodePaymentSignatureHeader(payload x402.PaymentPayload) map[string]string { + switch payload.X402Version { + case 2: + return map[string]string{ + "PAYMENT-SIGNATURE": encodePaymentSignatureHeader(payload), + } + case 1: + return map[string]string{ + "X-PAYMENT": encodePaymentSignatureHeader(payload), + } + default: + panic(fmt.Sprintf("unsupported x402 version: %d", payload.X402Version)) + } +} + +// GetPaymentRequiredResponse extracts payment requirements from HTTP response +// Handles both v1 (body) and v2 (header) formats +func (c *x402HTTPClient) GetPaymentRequiredResponse(headers map[string]string, body []byte) (x402.PaymentRequired, error) { + // Normalize headers to uppercase + normalizedHeaders := make(map[string]string) + for k, v := range headers { + normalizedHeaders[strings.ToUpper(k)] = v + } + + // Check v2 header first + if header, exists := normalizedHeaders["PAYMENT-REQUIRED"]; exists { + return decodePaymentRequiredHeader(header) + } + + // Fall back to v1 body format + if len(body) > 0 { + var required x402.PaymentRequired + if err := json.Unmarshal(body, &required); err == nil { + if required.X402Version == 1 { + return required, nil + } + } + } + + return x402.PaymentRequired{}, fmt.Errorf("no payment required information found in response") +} + +// GetPaymentSettleResponse extracts settlement response from HTTP headers +func (c *x402HTTPClient) GetPaymentSettleResponse(headers map[string]string) (x402.SettleResponse, error) { + // Normalize headers to uppercase + normalizedHeaders := make(map[string]string) + for k, v := range headers { + normalizedHeaders[strings.ToUpper(k)] = v + } + + // Check v2 header + if header, exists := normalizedHeaders["PAYMENT-RESPONSE"]; exists { + return decodePaymentResponseHeader(header) + } + + // Check v1 header + if header, exists := normalizedHeaders["X-PAYMENT-RESPONSE"]; exists { + return decodePaymentResponseHeader(header) + } + + return x402.SettleResponse{}, fmt.Errorf("payment response header not found") +} + +// ============================================================================ +// HTTP Client Wrapper +// ============================================================================ + +// WrapHTTPClientWithPayment wraps a standard HTTP client with x402 payment handling +// This allows transparent payment handling for HTTP requests +func WrapHTTPClientWithPayment(client *http.Client, x402Client *x402HTTPClient) *http.Client { + if client == nil { + client = http.DefaultClient + } + + // Wrap the transport with payment handling + originalTransport := client.Transport + if originalTransport == nil { + originalTransport = http.DefaultTransport + } + + client.Transport = &PaymentRoundTripper{ + Transport: originalTransport, + x402Client: x402Client, + retryCount: &sync.Map{}, + } + + return client +} + +// PaymentRoundTripper implements http.RoundTripper with x402 payment handling +type PaymentRoundTripper struct { + Transport http.RoundTripper + x402Client *x402HTTPClient + retryCount *sync.Map // Track retry count per request to prevent infinite loops +} + +// RoundTrip implements http.RoundTripper +func (t *PaymentRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + // Get or initialize retry count for this request + requestID := fmt.Sprintf("%p", req) + count, _ := t.retryCount.LoadOrStore(requestID, 0) + retries := count.(int) + + // Prevent infinite retry loops + if retries > 1 { + t.retryCount.Delete(requestID) + return nil, fmt.Errorf("payment retry limit exceeded") + } + + // Make initial request + resp, err := t.Transport.RoundTrip(req) + if err != nil { + t.retryCount.Delete(requestID) + return nil, err + } + + // If not 402, return as-is + if resp.StatusCode != http.StatusPaymentRequired { + t.retryCount.Delete(requestID) + return resp, nil + } + + // Increment retry count + t.retryCount.Store(requestID, retries+1) + + // Extract payment requirements + headers := make(map[string]string) + for k, v := range resp.Header { + if len(v) > 0 { + headers[k] = v[0] + } + } + + // Read body if present (for v1 compatibility) + var body []byte + if resp.Body != nil { + body, err = io.ReadAll(resp.Body) + resp.Body.Close() + if err != nil { + t.retryCount.Delete(requestID) + return nil, fmt.Errorf("failed to read 402 response body: %w", err) + } + } + + // Parse payment requirements + paymentRequired, err := t.x402Client.GetPaymentRequiredResponse(headers, body) + if err != nil { + t.retryCount.Delete(requestID) + return nil, fmt.Errorf("failed to parse payment requirements: %w", err) + } + + // Select and create payment + selected, err := t.x402Client.SelectPaymentRequirements(paymentRequired.X402Version, paymentRequired.Accepts) + if err != nil { + t.retryCount.Delete(requestID) + return nil, fmt.Errorf("cannot fulfill payment requirements: %w", err) + } + + ctx := req.Context() + if ctx == nil { + ctx = context.Background() + } + + payload, err := t.x402Client.CreatePaymentPayload(ctx, paymentRequired.X402Version, selected) + if err != nil { + t.retryCount.Delete(requestID) + return nil, fmt.Errorf("failed to create payment: %w", err) + } + + // Create new request with payment header + paymentReq := req.Clone(ctx) + paymentHeaders := t.x402Client.EncodePaymentSignatureHeader(payload) + for k, v := range paymentHeaders { + paymentReq.Header.Set(k, v) + } + + // Retry with payment + newResp, err := t.Transport.RoundTrip(paymentReq) + t.retryCount.Delete(requestID) + return newResp, err +} + +// ============================================================================ +// Convenience Methods +// ============================================================================ + +// DoWithPayment performs an HTTP request with automatic payment handling +func (c *x402HTTPClient) DoWithPayment(ctx context.Context, req *http.Request) (*http.Response, error) { + // Create a client with our transport + client := &http.Client{ + Transport: &PaymentRoundTripper{ + Transport: http.DefaultTransport, + x402Client: c, + retryCount: &sync.Map{}, + }, + } + + return client.Do(req.WithContext(ctx)) +} + +// GetWithPayment performs a GET request with automatic payment handling +func (c *x402HTTPClient) GetWithPayment(ctx context.Context, url string) (*http.Response, error) { + req, err := http.NewRequestWithContext(ctx, "GET", url, nil) + if err != nil { + return nil, err + } + return c.DoWithPayment(ctx, req) +} + +// PostWithPayment performs a POST request with automatic payment handling +func (c *x402HTTPClient) PostWithPayment(ctx context.Context, url string, body io.Reader) (*http.Response, error) { + req, err := http.NewRequestWithContext(ctx, "POST", url, body) + if err != nil { + return nil, err + } + return c.DoWithPayment(ctx, req) +} + +// ============================================================================ +// Header Encoding/Decoding Functions +// ============================================================================ + +// encodePaymentSignatureHeader encodes a payment payload as base64 +func encodePaymentSignatureHeader(payload x402.PaymentPayload) string { + data, err := json.Marshal(payload) + if err != nil { + panic(fmt.Sprintf("failed to marshal payment payload: %v", err)) + } + return base64.StdEncoding.EncodeToString(data) +} + +// decodePaymentSignatureHeader decodes a base64 payment signature header +func decodePaymentSignatureHeader(header string) (x402.PaymentPayload, error) { + data, err := base64.StdEncoding.DecodeString(header) + if err != nil { + return x402.PaymentPayload{}, fmt.Errorf("invalid base64 encoding: %w", err) + } + + var payload x402.PaymentPayload + if err := json.Unmarshal(data, &payload); err != nil { + return x402.PaymentPayload{}, fmt.Errorf("invalid payment payload JSON: %w", err) + } + + return payload, nil +} + +// encodePaymentRequiredHeader encodes payment requirements as base64 +func encodePaymentRequiredHeader(required x402.PaymentRequired) string { + data, err := json.Marshal(required) + if err != nil { + panic(fmt.Sprintf("failed to marshal payment required: %v", err)) + } + return base64.StdEncoding.EncodeToString(data) +} + +// decodePaymentRequiredHeader decodes a base64 payment required header +func decodePaymentRequiredHeader(header string) (x402.PaymentRequired, error) { + data, err := base64.StdEncoding.DecodeString(header) + if err != nil { + return x402.PaymentRequired{}, fmt.Errorf("invalid base64 encoding: %w", err) + } + + var required x402.PaymentRequired + if err := json.Unmarshal(data, &required); err != nil { + return x402.PaymentRequired{}, fmt.Errorf("invalid payment required JSON: %w", err) + } + + return required, nil +} + +// encodePaymentResponseHeader encodes a settlement response as base64 +func encodePaymentResponseHeader(response x402.SettleResponse) string { + data, err := json.Marshal(response) + if err != nil { + panic(fmt.Sprintf("failed to marshal settle response: %v", err)) + } + return base64.StdEncoding.EncodeToString(data) +} + +// decodePaymentResponseHeader decodes a base64 payment response header +func decodePaymentResponseHeader(header string) (x402.SettleResponse, error) { + data, err := base64.StdEncoding.DecodeString(header) + if err != nil { + return x402.SettleResponse{}, fmt.Errorf("invalid base64 encoding: %w", err) + } + + var response x402.SettleResponse + if err := json.Unmarshal(data, &response); err != nil { + return x402.SettleResponse{}, fmt.Errorf("invalid settle response JSON: %w", err) + } + + return response, nil +} diff --git a/go/http/client_test.go b/go/http/client_test.go new file mode 100644 index 000000000..3c20c7abc --- /dev/null +++ b/go/http/client_test.go @@ -0,0 +1,389 @@ +package http + +import ( + "context" + "encoding/base64" + "encoding/json" + "io" + "net/http" + "net/http/httptest" + "strings" + "testing" + + x402 "github.com/coinbase/x402-go/v2" +) + +func TestNewx402HTTPClient(t *testing.T) { + client := Newx402HTTPClient() + if client == nil { + t.Fatal("Expected client to be created") + } + if client.X402Client == nil { + t.Fatal("Expected embedded x402Client") + } +} + +func TestEncodePaymentSignatureHeader(t *testing.T) { + client := Newx402HTTPClient() + + tests := []struct { + name string + payload x402.PaymentPayload + expected string + }{ + { + name: "v2 payload", + payload: x402.PaymentPayload{ + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + Payload: map[string]interface{}{"sig": "test"}, + }, + expected: "PAYMENT-SIGNATURE", + }, + { + name: "v1 payload", + payload: x402.PaymentPayload{ + X402Version: 1, + Scheme: "exact", + Network: "eip155:1", + Payload: map[string]interface{}{"sig": "test"}, + }, + expected: "X-PAYMENT", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + headers := client.EncodePaymentSignatureHeader(tt.payload) + if _, exists := headers[tt.expected]; !exists { + t.Errorf("Expected header %s not found", tt.expected) + } + + // Verify it's base64 encoded JSON + encoded := headers[tt.expected] + decoded, err := base64.StdEncoding.DecodeString(encoded) + if err != nil { + t.Fatalf("Failed to decode base64: %v", err) + } + + var decodedPayload x402.PaymentPayload + if err := json.Unmarshal(decoded, &decodedPayload); err != nil { + t.Fatalf("Failed to unmarshal JSON: %v", err) + } + + if decodedPayload.X402Version != tt.payload.X402Version { + t.Errorf("Version mismatch: got %d, want %d", decodedPayload.X402Version, tt.payload.X402Version) + } + }) + } +} + +func TestGetPaymentRequiredResponse(t *testing.T) { + client := Newx402HTTPClient() + + // Test v2 header format + requirements := x402.PaymentRequired{ + X402Version: 2, + Error: "Payment required", + Accepts: []x402.PaymentRequirements{ + { + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + }, + }, + } + + reqJSON, _ := json.Marshal(requirements) + encoded := base64.StdEncoding.EncodeToString(reqJSON) + + headers := map[string]string{ + "PAYMENT-REQUIRED": encoded, + } + + result, err := client.GetPaymentRequiredResponse(headers, nil) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + if result.X402Version != 2 { + t.Errorf("Expected version 2, got %d", result.X402Version) + } + if len(result.Accepts) != 1 { + t.Errorf("Expected 1 requirement, got %d", len(result.Accepts)) + } + + // Test v1 body format + v1Requirements := x402.PaymentRequired{ + X402Version: 1, + Error: "Payment required", + Accepts: []x402.PaymentRequirements{ + { + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + }, + }, + } + + v1Body, _ := json.Marshal(v1Requirements) + + result, err = client.GetPaymentRequiredResponse(map[string]string{}, v1Body) + if err != nil { + t.Fatalf("Unexpected error for v1: %v", err) + } + + if result.X402Version != 1 { + t.Errorf("Expected version 1, got %d", result.X402Version) + } + + // Test no payment required found + _, err = client.GetPaymentRequiredResponse(map[string]string{}, nil) + if err == nil { + t.Error("Expected error when no payment required found") + } +} + +func TestGetPaymentSettleResponse(t *testing.T) { + client := Newx402HTTPClient() + + settleResponse := x402.SettleResponse{ + Success: true, + Transaction: "0xtx", + Payer: "0xpayer", + Network: "eip155:1", + } + + respJSON, _ := json.Marshal(settleResponse) + encoded := base64.StdEncoding.EncodeToString(respJSON) + + // Test v2 header + headers := map[string]string{ + "PAYMENT-RESPONSE": encoded, + } + + result, err := client.GetPaymentSettleResponse(headers) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + if !result.Success { + t.Error("Expected success") + } + if result.Transaction != "0xtx" { + t.Errorf("Expected transaction 0xtx, got %s", result.Transaction) + } + + // Test v1 header + headers = map[string]string{ + "X-PAYMENT-RESPONSE": encoded, + } + + result, err = client.GetPaymentSettleResponse(headers) + if err != nil { + t.Fatalf("Unexpected error for v1: %v", err) + } + + if result.Payer != "0xpayer" { + t.Errorf("Expected payer 0xpayer, got %s", result.Payer) + } + + // Test no header found + _, err = client.GetPaymentSettleResponse(map[string]string{}) + if err == nil { + t.Error("Expected error when no payment response found") + } +} + +func TestPaymentRoundTripper(t *testing.T) { + // Create a test server that returns 402 first, then 200 + callCount := 0 + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + callCount++ + + if callCount == 1 { + // First call - return 402 + requirements := x402.PaymentRequired{ + X402Version: 2, + Error: "Payment required", + Accepts: []x402.PaymentRequirements{ + { + Scheme: "mock", + Network: "test:1", + Asset: "TEST", + Amount: "1000", + PayTo: "0xtest", + }, + }, + } + + reqJSON, _ := json.Marshal(requirements) + encoded := base64.StdEncoding.EncodeToString(reqJSON) + + w.Header().Set("PAYMENT-REQUIRED", encoded) + w.WriteHeader(http.StatusPaymentRequired) + w.Write([]byte("Payment required")) + } else { + // Second call - check for payment header and return 200 + if r.Header.Get("PAYMENT-SIGNATURE") == "" { + t.Error("Expected PAYMENT-SIGNATURE header on retry") + } + w.WriteHeader(http.StatusOK) + w.Write([]byte("Success")) + } + })) + defer server.Close() + + // Create mock scheme client + mockClient := &mockSchemeClient{ + scheme: "mock", + createPayload: func(ctx context.Context, version int, requirements x402.PaymentRequirements) (x402.PaymentPayload, error) { + return x402.PaymentPayload{ + X402Version: version, + Scheme: "mock", + Network: requirements.Network, + Payload: map[string]interface{}{"sig": "test"}, + }, nil + }, + } + + // Create x402 HTTP client + x402Client := Newx402HTTPClient() + x402Client.RegisterScheme("test:1", mockClient) + + // Wrap standard HTTP client + httpClient := WrapHTTPClientWithPayment(http.DefaultClient, x402Client) + + // Make request + resp, err := httpClient.Get(server.URL) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + t.Errorf("Expected status 200, got %d", resp.StatusCode) + } + + body, _ := io.ReadAll(resp.Body) + if string(body) != "Success" { + t.Errorf("Expected body 'Success', got %s", string(body)) + } + + if callCount != 2 { + t.Errorf("Expected 2 calls to server, got %d", callCount) + } +} + +func TestPaymentRoundTripperNoRetryOn200(t *testing.T) { + // Server that always returns 200 + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + w.Write([]byte("Success")) + })) + defer server.Close() + + x402Client := Newx402HTTPClient() + httpClient := WrapHTTPClientWithPayment(http.DefaultClient, x402Client) + + resp, err := httpClient.Get(server.URL) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + t.Errorf("Expected status 200, got %d", resp.StatusCode) + } +} + +func TestDoWithPayment(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + w.Write([]byte("Success")) + })) + defer server.Close() + + client := Newx402HTTPClient() + ctx := context.Background() + req, _ := http.NewRequest("GET", server.URL, nil) + + resp, err := client.DoWithPayment(ctx, req) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + t.Errorf("Expected status 200, got %d", resp.StatusCode) + } +} + +func TestGetWithPayment(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" { + t.Errorf("Expected GET, got %s", r.Method) + } + w.WriteHeader(http.StatusOK) + })) + defer server.Close() + + client := Newx402HTTPClient() + ctx := context.Background() + + resp, err := client.GetWithPayment(ctx, server.URL) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + defer resp.Body.Close() +} + +func TestPostWithPayment(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + t.Errorf("Expected POST, got %s", r.Method) + } + body, _ := io.ReadAll(r.Body) + if string(body) != "test body" { + t.Errorf("Expected 'test body', got %s", string(body)) + } + w.WriteHeader(http.StatusOK) + })) + defer server.Close() + + client := Newx402HTTPClient() + ctx := context.Background() + + resp, err := client.PostWithPayment(ctx, server.URL, strings.NewReader("test body")) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + defer resp.Body.Close() +} + +// Mock scheme client for testing +type mockSchemeClient struct { + scheme string + createPayload func(ctx context.Context, version int, requirements x402.PaymentRequirements) (x402.PaymentPayload, error) +} + +func (m *mockSchemeClient) Scheme() string { + return m.scheme +} + +func (m *mockSchemeClient) CreatePaymentPayload(ctx context.Context, version int, requirements x402.PaymentRequirements) (x402.PaymentPayload, error) { + if m.createPayload != nil { + return m.createPayload(ctx, version, requirements) + } + return x402.PaymentPayload{ + X402Version: version, + Scheme: m.scheme, + Network: requirements.Network, + Payload: map[string]interface{}{}, + }, nil +} diff --git a/go/http/facilitator_client.go b/go/http/facilitator_client.go new file mode 100644 index 000000000..d7a64dddd --- /dev/null +++ b/go/http/facilitator_client.go @@ -0,0 +1,408 @@ +package http + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "time" + + x402 "github.com/coinbase/x402-go/v2" +) + +// ============================================================================ +// HTTP Facilitator Client +// ============================================================================ + +// HTTPFacilitatorClient communicates with remote facilitator services over HTTP +type HTTPFacilitatorClient struct { + url string + httpClient *http.Client + authProvider AuthProvider + identifier string +} + +// AuthProvider generates authentication headers for facilitator requests +type AuthProvider interface { + // GetAuthHeaders returns authentication headers for each endpoint + GetAuthHeaders(ctx context.Context) (AuthHeaders, error) +} + +// AuthHeaders contains authentication headers for facilitator endpoints +type AuthHeaders struct { + Verify map[string]string + Settle map[string]string + Supported map[string]string +} + +// FacilitatorConfig configures the HTTP facilitator client +type FacilitatorConfig struct { + // URL is the base URL of the facilitator service + URL string + + // HTTPClient is the HTTP client to use (optional) + HTTPClient *http.Client + + // AuthProvider provides authentication headers (optional) + AuthProvider AuthProvider + + // Timeout for requests (optional, defaults to 30s) + Timeout time.Duration + + // Identifier for this facilitator (optional) + Identifier string +} + +// DefaultFacilitatorURL is the default public facilitator +const DefaultFacilitatorURL = "https://x402.org/facilitator" + +// NewHTTPFacilitatorClient creates a new HTTP facilitator client +func NewHTTPFacilitatorClient(config *FacilitatorConfig) *HTTPFacilitatorClient { + if config == nil { + config = &FacilitatorConfig{} + } + + url := config.URL + if url == "" { + url = DefaultFacilitatorURL + } + + httpClient := config.HTTPClient + if httpClient == nil { + timeout := config.Timeout + if timeout == 0 { + timeout = 30 * time.Second + } + httpClient = &http.Client{ + Timeout: timeout, + } + } + + identifier := config.Identifier + if identifier == "" { + identifier = url + } + + return &HTTPFacilitatorClient{ + url: url, + httpClient: httpClient, + authProvider: config.AuthProvider, + identifier: identifier, + } +} + +// ============================================================================ +// FacilitatorClient Implementation +// ============================================================================ + +// Verify checks if a payment is valid without executing it +func (c *HTTPFacilitatorClient) Verify(ctx context.Context, payload x402.PaymentPayload, requirements x402.PaymentRequirements) (x402.VerifyResponse, error) { + // Build request body + requestBody := map[string]interface{}{ + "x402Version": payload.X402Version, + "paymentPayload": toJSONSafe(payload), + "paymentRequirements": toJSONSafe(requirements), + } + + body, err := json.Marshal(requestBody) + if err != nil { + return x402.VerifyResponse{}, fmt.Errorf("failed to marshal verify request: %w", err) + } + + // Create request + req, err := http.NewRequestWithContext(ctx, "POST", c.url+"/verify", bytes.NewReader(body)) + if err != nil { + return x402.VerifyResponse{}, fmt.Errorf("failed to create verify request: %w", err) + } + + req.Header.Set("Content-Type", "application/json") + + // Add auth headers if available + if c.authProvider != nil { + authHeaders, err := c.authProvider.GetAuthHeaders(ctx) + if err != nil { + return x402.VerifyResponse{}, fmt.Errorf("failed to get auth headers: %w", err) + } + for k, v := range authHeaders.Verify { + req.Header.Set(k, v) + } + } + + // Make request + resp, err := c.httpClient.Do(req) + if err != nil { + return x402.VerifyResponse{}, fmt.Errorf("verify request failed: %w", err) + } + defer resp.Body.Close() + + // Check status + if resp.StatusCode != http.StatusOK { + body, _ := io.ReadAll(resp.Body) + return x402.VerifyResponse{}, fmt.Errorf("facilitator verify failed (%d): %s", resp.StatusCode, string(body)) + } + + // Parse response + var verifyResponse x402.VerifyResponse + if err := json.NewDecoder(resp.Body).Decode(&verifyResponse); err != nil { + return x402.VerifyResponse{}, fmt.Errorf("failed to decode verify response: %w", err) + } + + return verifyResponse, nil +} + +// Settle executes a payment on-chain +func (c *HTTPFacilitatorClient) Settle(ctx context.Context, payload x402.PaymentPayload, requirements x402.PaymentRequirements) (x402.SettleResponse, error) { + // Build request body + requestBody := map[string]interface{}{ + "x402Version": payload.X402Version, + "paymentPayload": toJSONSafe(payload), + "paymentRequirements": toJSONSafe(requirements), + } + + body, err := json.Marshal(requestBody) + if err != nil { + return x402.SettleResponse{}, fmt.Errorf("failed to marshal settle request: %w", err) + } + + // Create request + req, err := http.NewRequestWithContext(ctx, "POST", c.url+"/settle", bytes.NewReader(body)) + if err != nil { + return x402.SettleResponse{}, fmt.Errorf("failed to create settle request: %w", err) + } + + req.Header.Set("Content-Type", "application/json") + + // Add auth headers if available + if c.authProvider != nil { + authHeaders, err := c.authProvider.GetAuthHeaders(ctx) + if err != nil { + return x402.SettleResponse{}, fmt.Errorf("failed to get auth headers: %w", err) + } + for k, v := range authHeaders.Settle { + req.Header.Set(k, v) + } + } + + // Make request + resp, err := c.httpClient.Do(req) + if err != nil { + return x402.SettleResponse{}, fmt.Errorf("settle request failed: %w", err) + } + defer resp.Body.Close() + + // Check status + if resp.StatusCode != http.StatusOK { + body, _ := io.ReadAll(resp.Body) + return x402.SettleResponse{}, fmt.Errorf("facilitator settle failed (%d): %s", resp.StatusCode, string(body)) + } + + // Parse response + var settleResponse x402.SettleResponse + if err := json.NewDecoder(resp.Body).Decode(&settleResponse); err != nil { + return x402.SettleResponse{}, fmt.Errorf("failed to decode settle response: %w", err) + } + + return settleResponse, nil +} + +// GetSupported returns the payment kinds this facilitator supports +func (c *HTTPFacilitatorClient) GetSupported(ctx context.Context) (x402.SupportedResponse, error) { + // Create request + req, err := http.NewRequestWithContext(ctx, "GET", c.url+"/supported", nil) + if err != nil { + return x402.SupportedResponse{}, fmt.Errorf("failed to create supported request: %w", err) + } + + req.Header.Set("Content-Type", "application/json") + + // Add auth headers if available + if c.authProvider != nil { + authHeaders, err := c.authProvider.GetAuthHeaders(ctx) + if err != nil { + return x402.SupportedResponse{}, fmt.Errorf("failed to get auth headers: %w", err) + } + for k, v := range authHeaders.Supported { + req.Header.Set(k, v) + } + } + + // Make request + resp, err := c.httpClient.Do(req) + if err != nil { + return x402.SupportedResponse{}, fmt.Errorf("supported request failed: %w", err) + } + defer resp.Body.Close() + + // Check status + if resp.StatusCode != http.StatusOK { + body, _ := io.ReadAll(resp.Body) + return x402.SupportedResponse{}, fmt.Errorf("facilitator getSupported failed (%d): %s", resp.StatusCode, string(body)) + } + + // Parse response + var supportedResponse x402.SupportedResponse + if err := json.NewDecoder(resp.Body).Decode(&supportedResponse); err != nil { + return x402.SupportedResponse{}, fmt.Errorf("failed to decode supported response: %w", err) + } + + return supportedResponse, nil +} + +// Identifier returns the identifier for this facilitator client +func (c *HTTPFacilitatorClient) Identifier() string { + return c.identifier +} + +// ============================================================================ +// Authentication Providers +// ============================================================================ + +// StaticAuthProvider provides static authentication headers +type StaticAuthProvider struct { + headers AuthHeaders +} + +// NewStaticAuthProvider creates an auth provider with static headers +func NewStaticAuthProvider(apiKey string) *StaticAuthProvider { + headers := map[string]string{ + "Authorization": "Bearer " + apiKey, + } + return &StaticAuthProvider{ + headers: AuthHeaders{ + Verify: headers, + Settle: headers, + Supported: headers, + }, + } +} + +// GetAuthHeaders returns the static headers +func (p *StaticAuthProvider) GetAuthHeaders(ctx context.Context) (AuthHeaders, error) { + return p.headers, nil +} + +// FuncAuthProvider uses functions to generate auth headers +type FuncAuthProvider struct { + fn func(ctx context.Context) (AuthHeaders, error) +} + +// NewFuncAuthProvider creates an auth provider from a function +func NewFuncAuthProvider(fn func(ctx context.Context) (AuthHeaders, error)) *FuncAuthProvider { + return &FuncAuthProvider{fn: fn} +} + +// GetAuthHeaders calls the function to get headers +func (p *FuncAuthProvider) GetAuthHeaders(ctx context.Context) (AuthHeaders, error) { + return p.fn(ctx) +} + +// ============================================================================ +// Multiple Facilitator Client +// ============================================================================ + +// MultiFacilitatorClient tries multiple facilitators in order +type MultiFacilitatorClient struct { + clients []x402.FacilitatorClient +} + +// NewMultiFacilitatorClient creates a client that tries multiple facilitators +func NewMultiFacilitatorClient(clients ...x402.FacilitatorClient) *MultiFacilitatorClient { + return &MultiFacilitatorClient{ + clients: clients, + } +} + +// Verify tries each facilitator until one succeeds +func (m *MultiFacilitatorClient) Verify(ctx context.Context, payload x402.PaymentPayload, requirements x402.PaymentRequirements) (x402.VerifyResponse, error) { + var lastErr error + + for _, client := range m.clients { + resp, err := client.Verify(ctx, payload, requirements) + if err == nil { + return resp, nil + } + lastErr = err + } + + if lastErr != nil { + return x402.VerifyResponse{}, fmt.Errorf("all facilitators failed: %w", lastErr) + } + + return x402.VerifyResponse{}, fmt.Errorf("no facilitators configured") +} + +// Settle tries each facilitator until one succeeds +func (m *MultiFacilitatorClient) Settle(ctx context.Context, payload x402.PaymentPayload, requirements x402.PaymentRequirements) (x402.SettleResponse, error) { + var lastErr error + + for _, client := range m.clients { + resp, err := client.Settle(ctx, payload, requirements) + if err == nil { + return resp, nil + } + lastErr = err + } + + if lastErr != nil { + return x402.SettleResponse{}, fmt.Errorf("all facilitators failed: %w", lastErr) + } + + return x402.SettleResponse{}, fmt.Errorf("no facilitators configured") +} + +// GetSupported returns combined supported kinds from all facilitators +func (m *MultiFacilitatorClient) GetSupported(ctx context.Context) (x402.SupportedResponse, error) { + combined := x402.SupportedResponse{ + Kinds: []x402.SupportedKind{}, + Extensions: []string{}, + } + + extensionSet := make(map[string]bool) + + for _, client := range m.clients { + resp, err := client.GetSupported(ctx) + if err != nil { + continue // Skip failed facilitators + } + + combined.Kinds = append(combined.Kinds, resp.Kinds...) + + for _, ext := range resp.Extensions { + extensionSet[ext] = true + } + } + + for ext := range extensionSet { + combined.Extensions = append(combined.Extensions, ext) + } + + if len(combined.Kinds) == 0 { + return combined, fmt.Errorf("no facilitators returned supported kinds") + } + + return combined, nil +} + +// Identifier returns a combined identifier for multiple facilitators +func (m *MultiFacilitatorClient) Identifier() string { + return "multi-facilitator" +} + +// ============================================================================ +// Utility Functions +// ============================================================================ + +// toJSONSafe converts values to JSON-safe format (handles BigInt, etc.) +func toJSONSafe(v interface{}) interface{} { + // Marshal and unmarshal to normalize + data, err := json.Marshal(v) + if err != nil { + return v + } + + var result interface{} + json.Unmarshal(data, &result) + return result +} diff --git a/go/http/facilitator_client_test.go b/go/http/facilitator_client_test.go new file mode 100644 index 000000000..01a8843d7 --- /dev/null +++ b/go/http/facilitator_client_test.go @@ -0,0 +1,504 @@ +package http + +import ( + "context" + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + x402 "github.com/coinbase/x402-go/v2" +) + +func TestNewHTTPFacilitatorClient(t *testing.T) { + // Test with default config + client := NewHTTPFacilitatorClient(nil) + if client == nil { + t.Fatal("Expected client to be created") + } + if client.url != DefaultFacilitatorURL { + t.Errorf("Expected default URL %s, got %s", DefaultFacilitatorURL, client.url) + } + if client.identifier != DefaultFacilitatorURL { + t.Errorf("Expected default identifier %s, got %s", DefaultFacilitatorURL, client.identifier) + } + + // Test with custom config + config := &FacilitatorConfig{ + URL: "https://custom.facilitator.com", + Identifier: "custom", + } + + client = NewHTTPFacilitatorClient(config) + if client.url != config.URL { + t.Errorf("Expected URL %s, got %s", config.URL, client.url) + } + if client.identifier != "custom" { + t.Errorf("Expected identifier 'custom', got %s", client.identifier) + } +} + +func TestHTTPFacilitatorClientVerify(t *testing.T) { + ctx := context.Background() + + // Create test server + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/verify" { + t.Errorf("Expected path /verify, got %s", r.URL.Path) + } + if r.Method != "POST" { + t.Errorf("Expected POST, got %s", r.Method) + } + + // Check request body + var requestBody map[string]interface{} + if err := json.NewDecoder(r.Body).Decode(&requestBody); err != nil { + t.Fatalf("Failed to decode request: %v", err) + } + + if requestBody["x402Version"].(float64) != 2 { + t.Error("Expected version 2 in request") + } + + // Return success response + response := x402.VerifyResponse{ + IsValid: true, + Payer: "0xverifiedpayer", + } + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(response) + })) + defer server.Close() + + client := NewHTTPFacilitatorClient(&FacilitatorConfig{ + URL: server.URL, + }) + + payload := x402.PaymentPayload{ + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + Payload: map[string]interface{}{"sig": "test"}, + } + + requirements := x402.PaymentRequirements{ + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + } + + response, err := client.Verify(ctx, payload, requirements) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + if !response.IsValid { + t.Error("Expected valid response") + } + if response.Payer != "0xverifiedpayer" { + t.Errorf("Expected payer 0xverifiedpayer, got %s", response.Payer) + } +} + +func TestHTTPFacilitatorClientSettle(t *testing.T) { + ctx := context.Background() + + // Create test server + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/settle" { + t.Errorf("Expected path /settle, got %s", r.URL.Path) + } + + // Return success response + response := x402.SettleResponse{ + Success: true, + Transaction: "0xsettledtx", + Payer: "0xpayer", + Network: "eip155:1", + } + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(response) + })) + defer server.Close() + + client := NewHTTPFacilitatorClient(&FacilitatorConfig{ + URL: server.URL, + }) + + payload := x402.PaymentPayload{ + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + Payload: map[string]interface{}{}, + } + + requirements := x402.PaymentRequirements{ + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + } + + response, err := client.Settle(ctx, payload, requirements) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + if !response.Success { + t.Error("Expected successful settlement") + } + if response.Transaction != "0xsettledtx" { + t.Errorf("Expected transaction 0xsettledtx, got %s", response.Transaction) + } +} + +func TestHTTPFacilitatorClientGetSupported(t *testing.T) { + ctx := context.Background() + + // Create test server + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/supported" { + t.Errorf("Expected path /supported, got %s", r.URL.Path) + } + if r.Method != "GET" { + t.Errorf("Expected GET, got %s", r.Method) + } + + // Return supported response + response := x402.SupportedResponse{ + Kinds: []x402.SupportedKind{ + { + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + }, + { + X402Version: 2, + Scheme: "exact", + Network: "eip155:8453", + }, + }, + Extensions: []string{"bazaar"}, + } + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(response) + })) + defer server.Close() + + client := NewHTTPFacilitatorClient(&FacilitatorConfig{ + URL: server.URL, + }) + + response, err := client.GetSupported(ctx) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + if len(response.Kinds) != 2 { + t.Errorf("Expected 2 kinds, got %d", len(response.Kinds)) + } + if len(response.Extensions) != 1 { + t.Errorf("Expected 1 extension, got %d", len(response.Extensions)) + } + if response.Extensions[0] != "bazaar" { + t.Errorf("Expected 'bazaar' extension, got %s", response.Extensions[0]) + } +} + +func TestHTTPFacilitatorClientWithAuth(t *testing.T) { + ctx := context.Background() + + // Create test server that checks auth headers + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + auth := r.Header.Get("Authorization") + if auth != "Bearer test-key" { + t.Errorf("Expected 'Bearer test-key', got %s", auth) + } + + // Return minimal response + if r.URL.Path == "/verify" { + json.NewEncoder(w).Encode(x402.VerifyResponse{IsValid: true}) + } else if r.URL.Path == "/settle" { + json.NewEncoder(w).Encode(x402.SettleResponse{Success: true}) + } else if r.URL.Path == "/supported" { + json.NewEncoder(w).Encode(x402.SupportedResponse{}) + } + })) + defer server.Close() + + client := NewHTTPFacilitatorClient(&FacilitatorConfig{ + URL: server.URL, + AuthProvider: NewStaticAuthProvider("test-key"), + }) + + // Test all endpoints with auth + payload := x402.PaymentPayload{ + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + Payload: map[string]interface{}{}, + } + + requirements := x402.PaymentRequirements{ + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + } + + // Verify + _, err := client.Verify(ctx, payload, requirements) + if err != nil { + t.Fatalf("Verify failed: %v", err) + } + + // Settle + _, err = client.Settle(ctx, payload, requirements) + if err != nil { + t.Fatalf("Settle failed: %v", err) + } + + // GetSupported + _, err = client.GetSupported(ctx) + if err != nil { + t.Fatalf("GetSupported failed: %v", err) + } +} + +func TestHTTPFacilitatorClientErrorHandling(t *testing.T) { + ctx := context.Background() + + // Create test server that returns errors + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte("Bad request")) + })) + defer server.Close() + + client := NewHTTPFacilitatorClient(&FacilitatorConfig{ + URL: server.URL, + }) + + payload := x402.PaymentPayload{ + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + Payload: map[string]interface{}{}, + } + + requirements := x402.PaymentRequirements{ + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + } + + // Test Verify error + _, err := client.Verify(ctx, payload, requirements) + if err == nil { + t.Error("Expected error for verify") + } + + // Test Settle error + _, err = client.Settle(ctx, payload, requirements) + if err == nil { + t.Error("Expected error for settle") + } + + // Test GetSupported error + _, err = client.GetSupported(ctx) + if err == nil { + t.Error("Expected error for getSupported") + } +} + +func TestStaticAuthProvider(t *testing.T) { + provider := NewStaticAuthProvider("api-key-123") + + ctx := context.Background() + headers, err := provider.GetAuthHeaders(ctx) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + expectedAuth := "Bearer api-key-123" + if headers.Verify["Authorization"] != expectedAuth { + t.Errorf("Expected verify auth %s, got %s", expectedAuth, headers.Verify["Authorization"]) + } + if headers.Settle["Authorization"] != expectedAuth { + t.Errorf("Expected settle auth %s, got %s", expectedAuth, headers.Settle["Authorization"]) + } + if headers.Supported["Authorization"] != expectedAuth { + t.Errorf("Expected supported auth %s, got %s", expectedAuth, headers.Supported["Authorization"]) + } +} + +func TestFuncAuthProvider(t *testing.T) { + provider := NewFuncAuthProvider(func(ctx context.Context) (AuthHeaders, error) { + return AuthHeaders{ + Verify: map[string]string{"X-API-Key": "verify-key"}, + Settle: map[string]string{"X-API-Key": "settle-key"}, + Supported: map[string]string{"X-API-Key": "supported-key"}, + }, nil + }) + + ctx := context.Background() + headers, err := provider.GetAuthHeaders(ctx) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + if headers.Verify["X-API-Key"] != "verify-key" { + t.Errorf("Expected verify key 'verify-key', got %s", headers.Verify["X-API-Key"]) + } + if headers.Settle["X-API-Key"] != "settle-key" { + t.Errorf("Expected settle key 'settle-key', got %s", headers.Settle["X-API-Key"]) + } + if headers.Supported["X-API-Key"] != "supported-key" { + t.Errorf("Expected supported key 'supported-key', got %s", headers.Supported["X-API-Key"]) + } +} + +func TestMultiFacilitatorClient(t *testing.T) { + ctx := context.Background() + + // Create mock facilitator clients + client1 := &mockMultiFacilitatorClient{ + id: "client1", + verifyFunc: func(ctx context.Context, p x402.PaymentPayload, r x402.PaymentRequirements) (x402.VerifyResponse, error) { + if p.Scheme == "exact" { + return x402.VerifyResponse{IsValid: true, Payer: "client1"}, nil + } + return x402.VerifyResponse{}, &x402.PaymentError{Message: "unsupported"} + }, + supportedFunc: func(ctx context.Context) (x402.SupportedResponse, error) { + return x402.SupportedResponse{ + Kinds: []x402.SupportedKind{ + {X402Version: 2, Scheme: "exact", Network: "eip155:1"}, + }, + Extensions: []string{"ext1"}, + }, nil + }, + } + + client2 := &mockMultiFacilitatorClient{ + id: "client2", + verifyFunc: func(ctx context.Context, p x402.PaymentPayload, r x402.PaymentRequirements) (x402.VerifyResponse, error) { + if p.Scheme == "transfer" { + return x402.VerifyResponse{IsValid: true, Payer: "client2"}, nil + } + return x402.VerifyResponse{}, &x402.PaymentError{Message: "unsupported"} + }, + supportedFunc: func(ctx context.Context) (x402.SupportedResponse, error) { + return x402.SupportedResponse{ + Kinds: []x402.SupportedKind{ + {X402Version: 2, Scheme: "transfer", Network: "eip155:8453"}, + }, + Extensions: []string{"ext2"}, + }, nil + }, + } + + multiClient := NewMultiFacilitatorClient(client1, client2) + + // Test Verify - should use client1 for "exact" + payload1 := x402.PaymentPayload{ + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + Payload: map[string]interface{}{}, + } + + requirements1 := x402.PaymentRequirements{ + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + } + + response, err := multiClient.Verify(ctx, payload1, requirements1) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if response.Payer != "client1" { + t.Errorf("Expected payer 'client1', got %s", response.Payer) + } + + // Test Verify - should use client2 for "transfer" + payload2 := x402.PaymentPayload{ + X402Version: 2, + Scheme: "transfer", + Network: "eip155:8453", + Payload: map[string]interface{}{}, + } + + requirements2 := x402.PaymentRequirements{ + Scheme: "transfer", + Network: "eip155:8453", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + } + + response, err = multiClient.Verify(ctx, payload2, requirements2) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if response.Payer != "client2" { + t.Errorf("Expected payer 'client2', got %s", response.Payer) + } + + // Test GetSupported - should combine from both + supported, err := multiClient.GetSupported(ctx) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if len(supported.Kinds) != 2 { + t.Errorf("Expected 2 kinds, got %d", len(supported.Kinds)) + } + if len(supported.Extensions) != 2 { + t.Errorf("Expected 2 extensions, got %d", len(supported.Extensions)) + } +} + +// Mock facilitator client for multi-client testing +type mockMultiFacilitatorClient struct { + id string + verifyFunc func(context.Context, x402.PaymentPayload, x402.PaymentRequirements) (x402.VerifyResponse, error) + settleFunc func(context.Context, x402.PaymentPayload, x402.PaymentRequirements) (x402.SettleResponse, error) + supportedFunc func(context.Context) (x402.SupportedResponse, error) +} + +func (m *mockMultiFacilitatorClient) Verify(ctx context.Context, p x402.PaymentPayload, r x402.PaymentRequirements) (x402.VerifyResponse, error) { + if m.verifyFunc != nil { + return m.verifyFunc(ctx, p, r) + } + return x402.VerifyResponse{}, nil +} + +func (m *mockMultiFacilitatorClient) Settle(ctx context.Context, p x402.PaymentPayload, r x402.PaymentRequirements) (x402.SettleResponse, error) { + if m.settleFunc != nil { + return m.settleFunc(ctx, p, r) + } + return x402.SettleResponse{}, nil +} + +func (m *mockMultiFacilitatorClient) GetSupported(ctx context.Context) (x402.SupportedResponse, error) { + if m.supportedFunc != nil { + return m.supportedFunc(ctx) + } + return x402.SupportedResponse{}, nil +} + +func (m *mockMultiFacilitatorClient) Identifier() string { + return m.id +} diff --git a/go/http/gin/middleware.go b/go/http/gin/middleware.go new file mode 100644 index 000000000..8602e3bf6 --- /dev/null +++ b/go/http/gin/middleware.go @@ -0,0 +1,443 @@ +package gin + +import ( + "bytes" + "context" + "fmt" + "net/http" + "sync" + "time" + + x402 "github.com/coinbase/x402-go/v2" + x402http "github.com/coinbase/x402-go/v2/http" + "github.com/gin-gonic/gin" +) + +// ============================================================================ +// Gin Adapter Implementation +// ============================================================================ + +// GinAdapter implements HTTPAdapter for Gin framework +type GinAdapter struct { + ctx *gin.Context +} + +// NewGinAdapter creates a new Gin adapter +func NewGinAdapter(ctx *gin.Context) *GinAdapter { + return &GinAdapter{ctx: ctx} +} + +// GetHeader gets a request header +func (a *GinAdapter) GetHeader(name string) string { + return a.ctx.GetHeader(name) +} + +// GetMethod gets the HTTP method +func (a *GinAdapter) GetMethod() string { + return a.ctx.Request.Method +} + +// GetPath gets the request path +func (a *GinAdapter) GetPath() string { + return a.ctx.Request.URL.Path +} + +// GetURL gets the full request URL +func (a *GinAdapter) GetURL() string { + scheme := "http" + if a.ctx.Request.TLS != nil { + scheme = "https" + } + host := a.ctx.Request.Host + if host == "" { + host = a.ctx.GetHeader("Host") + } + return fmt.Sprintf("%s://%s%s", scheme, host, a.ctx.Request.URL.Path) +} + +// GetAcceptHeader gets the Accept header +func (a *GinAdapter) GetAcceptHeader() string { + return a.ctx.GetHeader("Accept") +} + +// GetUserAgent gets the User-Agent header +func (a *GinAdapter) GetUserAgent() string { + return a.ctx.GetHeader("User-Agent") +} + +// ============================================================================ +// Middleware Configuration +// ============================================================================ + +// MiddlewareConfig configures the payment middleware +type MiddlewareConfig struct { + // Routes configuration + Routes x402http.RoutesConfig + + // Facilitator client(s) + FacilitatorClients []x402.FacilitatorClient + + // Scheme registrations + Schemes []SchemeRegistration + + // Paywall configuration + PaywallConfig *x402http.PaywallConfig + + // Initialize on startup + InitializeOnStart bool + + // Custom error handler + ErrorHandler func(*gin.Context, error) + + // Custom settlement handler + SettlementHandler func(*gin.Context, x402.SettleResponse) + + // Context timeout for payment operations + Timeout time.Duration +} + +// SchemeRegistration registers a scheme with the service +type SchemeRegistration struct { + Network x402.Network + Service x402.SchemeNetworkService +} + +// MiddlewareOption configures the middleware +type MiddlewareOption func(*MiddlewareConfig) + +// WithFacilitatorClient adds a facilitator client +func WithFacilitatorClient(client x402.FacilitatorClient) MiddlewareOption { + return func(c *MiddlewareConfig) { + c.FacilitatorClients = append(c.FacilitatorClients, client) + } +} + +// WithScheme registers a scheme service +func WithScheme(network x402.Network, service x402.SchemeNetworkService) MiddlewareOption { + return func(c *MiddlewareConfig) { + c.Schemes = append(c.Schemes, SchemeRegistration{ + Network: network, + Service: service, + }) + } +} + +// WithPaywallConfig sets the paywall configuration +func WithPaywallConfig(config *x402http.PaywallConfig) MiddlewareOption { + return func(c *MiddlewareConfig) { + c.PaywallConfig = config + } +} + +// WithInitializeOnStart sets whether to initialize on startup +func WithInitializeOnStart(initialize bool) MiddlewareOption { + return func(c *MiddlewareConfig) { + c.InitializeOnStart = initialize + } +} + +// WithErrorHandler sets a custom error handler +func WithErrorHandler(handler func(*gin.Context, error)) MiddlewareOption { + return func(c *MiddlewareConfig) { + c.ErrorHandler = handler + } +} + +// WithSettlementHandler sets a custom settlement handler +func WithSettlementHandler(handler func(*gin.Context, x402.SettleResponse)) MiddlewareOption { + return func(c *MiddlewareConfig) { + c.SettlementHandler = handler + } +} + +// WithTimeout sets the context timeout for payment operations +func WithTimeout(timeout time.Duration) MiddlewareOption { + return func(c *MiddlewareConfig) { + c.Timeout = timeout + } +} + +// ============================================================================ +// Payment Middleware +// ============================================================================ + +// PaymentMiddleware creates Gin middleware for x402 payment handling +func PaymentMiddleware(routes x402http.RoutesConfig, opts ...MiddlewareOption) gin.HandlerFunc { + config := &MiddlewareConfig{ + Routes: routes, + FacilitatorClients: []x402.FacilitatorClient{}, + Schemes: []SchemeRegistration{}, + InitializeOnStart: true, + Timeout: 30 * time.Second, + } + + // Apply options + for _, opt := range opts { + opt(config) + } + + // Create service options + serviceOpts := []x402.ResourceServiceOption{} + for _, client := range config.FacilitatorClients { + serviceOpts = append(serviceOpts, x402.WithFacilitatorClient(client)) + } + + // Create HTTP service + service := x402http.Newx402HTTPResourceService(config.Routes, serviceOpts...) + + // Register schemes + for _, scheme := range config.Schemes { + service.RegisterScheme(scheme.Network, scheme.Service) + } + + // Initialize if requested + if config.InitializeOnStart { + ctx, cancel := context.WithTimeout(context.Background(), config.Timeout) + defer cancel() + + if err := service.Initialize(ctx); err != nil { + // Log initialization error but don't fail - facilitator might come online later + fmt.Printf("Warning: failed to initialize x402 service: %v\n", err) + } + } + + // Create middleware handler + return func(c *gin.Context) { + // Create context with timeout + ctx, cancel := context.WithTimeout(c.Request.Context(), config.Timeout) + defer cancel() + + // Create adapter and request context + adapter := NewGinAdapter(c) + reqCtx := x402http.HTTPRequestContext{ + Adapter: adapter, + Path: c.Request.URL.Path, + Method: c.Request.Method, + } + + // Process HTTP request + result := service.ProcessHTTPRequest(ctx, reqCtx, config.PaywallConfig) + + // Debug logging for request processing + fmt.Printf("šŸ” [GIN REQUEST DEBUG] Processed HTTP request\n") + fmt.Printf(" Result Type: %v\n", result.Type) + fmt.Printf(" Path: %s, Method: %s\n", reqCtx.Path, reqCtx.Method) + + // Handle result + switch result.Type { + case x402http.ResultNoPaymentRequired: + // No payment required, continue to next handler + c.Next() + + case x402http.ResultPaymentError: + // Payment required but not provided or invalid + handlePaymentError(c, result.Response, config) + + case x402http.ResultPaymentVerified: + // Payment verified, continue with settlement handling + handlePaymentVerified(c, service, ctx, result, config) + } + } +} + +// handlePaymentError handles payment error responses +func handlePaymentError(c *gin.Context, response *x402http.HTTPResponseInstructions, config *MiddlewareConfig) { + // Set status + c.Status(response.Status) + + // Set headers + for key, value := range response.Headers { + c.Header(key, value) + } + + // Send response body + if response.IsHTML { + c.Data(response.Status, "text/html; charset=utf-8", []byte(response.Body.(string))) + } else { + c.JSON(response.Status, response.Body) + } + + // Abort to prevent further handlers + c.Abort() +} + +// handlePaymentVerified handles verified payments with settlement +func handlePaymentVerified(c *gin.Context, service *x402http.HTTPService, ctx context.Context, result x402http.HTTPProcessResult, config *MiddlewareConfig) { + // Capture response for settlement + writer := &responseCapture{ + ResponseWriter: c.Writer, + body: &bytes.Buffer{}, + statusCode: http.StatusOK, + } + c.Writer = writer + + // Continue to protected handler + c.Next() + + // Check if aborted + if c.IsAborted() { + return + } + + // Restore original writer + c.Writer = writer.ResponseWriter + + // Don't settle if response failed + if writer.statusCode >= 400 { + // Write captured response + c.Writer.WriteHeader(writer.statusCode) + c.Writer.Write(writer.body.Bytes()) + return + } + + // Debug logging for settlement + fmt.Printf("šŸ” [GIN SETTLEMENT DEBUG] Starting settlement process\n") + fmt.Printf(" StatusCode: %d\n", writer.statusCode) + fmt.Printf(" Context Error: %v\n", ctx.Err()) + fmt.Printf(" PaymentPayload: %+v\n", result.PaymentPayload) + fmt.Printf(" PaymentRequirements: %+v\n", result.PaymentRequirements) + + // Process settlement + settlementHeaders, err := service.ProcessSettlement( + ctx, + *result.PaymentPayload, + *result.PaymentRequirements, + writer.statusCode, + ) + + fmt.Printf("šŸ” [GIN SETTLEMENT DEBUG] Settlement completed\n") + fmt.Printf(" Error: %v\n", err) + fmt.Printf(" Headers: %+v\n", settlementHeaders) + + if err != nil { + // Settlement failed + if config.ErrorHandler != nil { + config.ErrorHandler(c, fmt.Errorf("settlement failed: %w", err)) + } else { + // Default error handling + c.JSON(http.StatusInternalServerError, gin.H{ + "error": "Settlement failed", + "details": err.Error(), + }) + } + return + } + + // Add settlement headers + if settlementHeaders != nil { + for key, value := range settlementHeaders { + c.Header(key, value) + } + + // Call settlement handler if configured + if config.SettlementHandler != nil && settlementHeaders["PAYMENT-RESPONSE"] != "" { + // Decode settlement response + httpClient := x402http.Newx402HTTPClient() + headers := make(map[string]string) + for k, v := range settlementHeaders { + headers[k] = v + } + settleResponse, _ := httpClient.GetPaymentSettleResponse(headers) + config.SettlementHandler(c, settleResponse) + } + } + + // Write captured response + c.Writer.WriteHeader(writer.statusCode) + c.Writer.Write(writer.body.Bytes()) +} + +// ============================================================================ +// Response Capture +// ============================================================================ + +// responseCapture captures the response for settlement processing +type responseCapture struct { + gin.ResponseWriter + body *bytes.Buffer + statusCode int + written bool + mu sync.Mutex +} + +// WriteHeader captures the status code +func (w *responseCapture) WriteHeader(code int) { + w.mu.Lock() + defer w.mu.Unlock() + + if !w.written { + w.statusCode = code + w.written = true + } +} + +// Write captures the response body +func (w *responseCapture) Write(data []byte) (int, error) { + w.mu.Lock() + defer w.mu.Unlock() + + if !w.written { + w.WriteHeader(http.StatusOK) + } + return w.body.Write(data) +} + +// WriteString captures string responses +func (w *responseCapture) WriteString(s string) (int, error) { + return w.Write([]byte(s)) +} + +// ============================================================================ +// Convenience Functions +// ============================================================================ + +// SimplePaymentMiddleware creates middleware with common defaults +func SimplePaymentMiddleware(payTo string, price string, network x402.Network, facilitatorURL string) gin.HandlerFunc { + // Create facilitator client + facilitator := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{ + URL: facilitatorURL, + }) + + // Create routes for all endpoints + routes := x402http.RoutesConfig{ + "*": x402http.RouteConfig{ + Scheme: "exact", + PayTo: payTo, + Price: price, + Network: network, + }, + } + + return PaymentMiddleware(routes, + WithFacilitatorClient(facilitator), + WithInitializeOnStart(true), + ) +} + +// RouteSpecificMiddleware creates middleware with per-route configuration +func RouteSpecificMiddleware(facilitatorURL string) gin.HandlerFunc { + facilitator := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{ + URL: facilitatorURL, + }) + + routes := x402http.RoutesConfig{ + "GET /api/data": { + Scheme: "exact", + PayTo: "0x...", + Price: "$0.10", + Network: "eip155:8453", + Description: "API data access", + }, + "POST /api/compute": { + Scheme: "exact", + PayTo: "0x...", + Price: "$1.00", + Network: "eip155:8453", + Description: "Compute operation", + }, + } + + return PaymentMiddleware(routes, + WithFacilitatorClient(facilitator), + ) +} diff --git a/go/http/http.go b/go/http/http.go new file mode 100644 index 000000000..adf6a1706 --- /dev/null +++ b/go/http/http.go @@ -0,0 +1,67 @@ +// Package http provides HTTP-specific implementations of x402 components. +// This includes HTTP-aware clients, services, and facilitator clients. +package http + +import ( + "context" + "io" + "net/http" + + x402 "github.com/coinbase/x402-go/v2" +) + +// ============================================================================ +// Re-export main types for convenience +// ============================================================================ + +// HTTP Client types +type ( + // HTTPClient is an alias for x402HTTPClient + HTTPClient = x402HTTPClient + + // HTTPService is an alias for x402HTTPResourceService + HTTPService = x402HTTPResourceService +) + +// ============================================================================ +// Constructor functions with simpler names +// ============================================================================ + +// NewClient creates a new HTTP-aware x402 client +func NewClient(opts ...x402.ClientOption) *x402HTTPClient { + return Newx402HTTPClient(opts...) +} + +// NewService creates a new HTTP resource service +func NewService(routes RoutesConfig, opts ...x402.ResourceServiceOption) *x402HTTPResourceService { + return Newx402HTTPResourceService(routes, opts...) +} + +// NewFacilitatorClient creates a new HTTP facilitator client +func NewFacilitatorClient(config *FacilitatorConfig) *HTTPFacilitatorClient { + return NewHTTPFacilitatorClient(config) +} + +// ============================================================================ +// Convenience functions +// ============================================================================ + +// WrapClient wraps a standard HTTP client with x402 payment handling +func WrapClient(client *http.Client, x402Client *x402HTTPClient) *http.Client { + return WrapHTTPClientWithPayment(client, x402Client) +} + +// Get performs a GET request with automatic payment handling +func Get(ctx context.Context, url string, x402Client *x402HTTPClient) (*http.Response, error) { + return x402Client.GetWithPayment(ctx, url) +} + +// Post performs a POST request with automatic payment handling +func Post(ctx context.Context, url string, body io.Reader, x402Client *x402HTTPClient) (*http.Response, error) { + return x402Client.PostWithPayment(ctx, url, body) +} + +// Do performs an HTTP request with automatic payment handling +func Do(ctx context.Context, req *http.Request, x402Client *x402HTTPClient) (*http.Response, error) { + return x402Client.DoWithPayment(ctx, req) +} diff --git a/go/http/service.go b/go/http/service.go new file mode 100644 index 000000000..cda15d099 --- /dev/null +++ b/go/http/service.go @@ -0,0 +1,533 @@ +package http + +import ( + "context" + "encoding/json" + "fmt" + "html" + "net/url" + "regexp" + "strconv" + "strings" + + x402 "github.com/coinbase/x402-go/v2" +) + +// ============================================================================ +// HTTP Adapter Interface +// ============================================================================ + +// HTTPAdapter provides framework-agnostic HTTP operations +// Implement this for each web framework (Gin, Echo, net/http, etc.) +type HTTPAdapter interface { + GetHeader(name string) string + GetMethod() string + GetPath() string + GetURL() string + GetAcceptHeader() string + GetUserAgent() string +} + +// ============================================================================ +// Configuration Types +// ============================================================================ + +// PaywallConfig configures the HTML paywall for browser requests +type PaywallConfig struct { + CDPClientKey string `json:"cdpClientKey,omitempty"` + AppName string `json:"appName,omitempty"` + AppLogo string `json:"appLogo,omitempty"` + SessionTokenEndpoint string `json:"sessionTokenEndpoint,omitempty"` + CurrentURL string `json:"currentUrl,omitempty"` + Testnet bool `json:"testnet,omitempty"` +} + +// RouteConfig defines payment configuration for an HTTP endpoint +type RouteConfig struct { + // Payment configuration + Scheme string `json:"scheme"` + PayTo string `json:"payTo"` + Price x402.Price `json:"price"` + Network x402.Network `json:"network"` + MaxTimeoutSeconds int `json:"maxTimeoutSeconds,omitempty"` + Extra map[string]interface{} `json:"extra,omitempty"` + + // HTTP-specific metadata + Resource string `json:"resource,omitempty"` + Description string `json:"description,omitempty"` + MimeType string `json:"mimeType,omitempty"` + CustomPaywallHTML string `json:"customPaywallHtml,omitempty"` + Discoverable bool `json:"discoverable,omitempty"` + InputSchema interface{} `json:"inputSchema,omitempty"` + OutputSchema interface{} `json:"outputSchema,omitempty"` +} + +// RoutesConfig maps route patterns to configurations +type RoutesConfig map[string]RouteConfig + +// CompiledRoute is a parsed route ready for matching +type CompiledRoute struct { + Verb string + Regex *regexp.Regexp + Config RouteConfig +} + +// ============================================================================ +// Request/Response Types +// ============================================================================ + +// HTTPRequestContext encapsulates an HTTP request +type HTTPRequestContext struct { + Adapter HTTPAdapter + Path string + Method string + PaymentHeader string +} + +// HTTPResponseInstructions tells the framework how to respond +type HTTPResponseInstructions struct { + Status int `json:"status"` + Headers map[string]string `json:"headers"` + Body interface{} `json:"body,omitempty"` + IsHTML bool `json:"isHtml,omitempty"` +} + +// HTTPProcessResult indicates the result of processing a payment request +type HTTPProcessResult struct { + Type string + Response *HTTPResponseInstructions + PaymentPayload *x402.PaymentPayload + PaymentRequirements *x402.PaymentRequirements +} + +// Result type constants +const ( + ResultNoPaymentRequired = "no-payment-required" + ResultPaymentVerified = "payment-verified" + ResultPaymentError = "payment-error" +) + +// ============================================================================ +// x402HTTPResourceService +// ============================================================================ + +// x402HTTPResourceService provides HTTP-specific payment handling +type x402HTTPResourceService struct { + *x402.X402ResourceService + compiledRoutes []CompiledRoute +} + +// Newx402HTTPResourceService creates a new HTTP resource service +func Newx402HTTPResourceService(routes RoutesConfig, opts ...x402.ResourceServiceOption) *x402HTTPResourceService { + service := &x402HTTPResourceService{ + X402ResourceService: x402.Newx402ResourceService(opts...), + compiledRoutes: []CompiledRoute{}, + } + + // Handle both single route and multiple routes + normalizedRoutes := routes + if normalizedRoutes == nil { + normalizedRoutes = make(RoutesConfig) + } + + // Compile routes + for pattern, config := range normalizedRoutes { + verb, regex := parseRoutePattern(pattern) + service.compiledRoutes = append(service.compiledRoutes, CompiledRoute{ + Verb: verb, + Regex: regex, + Config: config, + }) + } + + return service +} + +// ProcessHTTPRequest handles an HTTP request and returns processing result +func (s *x402HTTPResourceService) ProcessHTTPRequest(ctx context.Context, reqCtx HTTPRequestContext, paywallConfig *PaywallConfig) HTTPProcessResult { + // Find matching route + routeConfig := s.getRouteConfig(reqCtx.Path, reqCtx.Method) + if routeConfig == nil { + return HTTPProcessResult{Type: ResultNoPaymentRequired} + } + + // Check for payment header + paymentPayload := s.extractPayment(reqCtx.Adapter) + + // Build payment requirements + requirements, err := s.BuildPaymentRequirements(ctx, x402.ResourceConfig{ + Scheme: routeConfig.Scheme, + PayTo: routeConfig.PayTo, + Price: routeConfig.Price, + Network: routeConfig.Network, + MaxTimeoutSeconds: routeConfig.MaxTimeoutSeconds, + }) + + if err != nil { + return HTTPProcessResult{ + Type: ResultPaymentError, + Response: &HTTPResponseInstructions{ + Status: 500, + Headers: map[string]string{"Content-Type": "application/json"}, + Body: map[string]string{"error": err.Error()}, + }, + } + } + + // Create resource info + resourceInfo := x402.ResourceInfo{ + URL: reqCtx.Adapter.GetURL(), + Description: routeConfig.Description, + MimeType: routeConfig.MimeType, + } + + // If no payment provided + if paymentPayload == nil { + paymentRequired := s.CreatePaymentRequiredResponse( + requirements, + resourceInfo, + "Payment required", + nil, + ) + + return HTTPProcessResult{ + Type: ResultPaymentError, + Response: s.createHTTPResponse( + paymentRequired, + s.isWebBrowser(reqCtx.Adapter), + paywallConfig, + routeConfig.CustomPaywallHTML, + ), + } + } + + // Find matching requirements + matchingReqs := s.FindMatchingRequirements(requirements, *paymentPayload) + if matchingReqs == nil { + paymentRequired := s.CreatePaymentRequiredResponse( + requirements, + resourceInfo, + "No matching payment requirements", + nil, + ) + + return HTTPProcessResult{ + Type: ResultPaymentError, + Response: s.createHTTPResponse(paymentRequired, false, paywallConfig, ""), + } + } + + // Verify payment + verifyResult, err := s.VerifyPayment(ctx, *paymentPayload, *matchingReqs) + if err != nil || !verifyResult.IsValid { + errorMsg := "Payment verification failed" + if err != nil { + errorMsg = err.Error() + } else if verifyResult.InvalidReason != "" { + errorMsg = verifyResult.InvalidReason + } + + paymentRequired := s.CreatePaymentRequiredResponse( + requirements, + resourceInfo, + errorMsg, + nil, + ) + + return HTTPProcessResult{ + Type: ResultPaymentError, + Response: s.createHTTPResponse(paymentRequired, false, paywallConfig, ""), + } + } + + // Payment verified + return HTTPProcessResult{ + Type: ResultPaymentVerified, + PaymentPayload: paymentPayload, + PaymentRequirements: matchingReqs, + } +} + +// ProcessSettlement handles settlement after successful response +func (s *x402HTTPResourceService) ProcessSettlement(ctx context.Context, payload x402.PaymentPayload, requirements x402.PaymentRequirements, responseStatus int) (map[string]string, error) { + // Don't settle if response failed + if responseStatus >= 400 { + return nil, nil + } + + settleResult, err := s.SettlePayment(ctx, payload, requirements) + if err != nil { + return nil, err + } + + return s.createSettlementHeaders(settleResult), nil +} + +// ============================================================================ +// Helper Methods +// ============================================================================ + +// getRouteConfig finds matching route configuration +func (s *x402HTTPResourceService) getRouteConfig(path, method string) *RouteConfig { + normalizedPath := normalizePath(path) + upperMethod := strings.ToUpper(method) + + for _, route := range s.compiledRoutes { + if route.Regex.MatchString(normalizedPath) && + (route.Verb == "*" || route.Verb == upperMethod) { + config := route.Config // Make a copy + return &config + } + } + + return nil +} + +// extractPayment extracts payment from headers +func (s *x402HTTPResourceService) extractPayment(adapter HTTPAdapter) *x402.PaymentPayload { + // Check v2 header + header := adapter.GetHeader("PAYMENT-SIGNATURE") + if header == "" { + header = adapter.GetHeader("payment-signature") + } + + if header != "" { + payload, err := decodePaymentSignatureHeader(header) + if err == nil { + return &payload + } + } + + // Check v1 header + header = adapter.GetHeader("X-PAYMENT") + if header == "" { + header = adapter.GetHeader("x-payment") + } + + if header != "" { + payload, err := decodePaymentSignatureHeader(header) + if err == nil { + return &payload + } + } + + return nil +} + +// isWebBrowser checks if request is from a web browser +func (s *x402HTTPResourceService) isWebBrowser(adapter HTTPAdapter) bool { + accept := adapter.GetAcceptHeader() + userAgent := adapter.GetUserAgent() + return strings.Contains(accept, "text/html") && strings.Contains(userAgent, "Mozilla") +} + +// createHTTPResponse creates response instructions +func (s *x402HTTPResourceService) createHTTPResponse(paymentRequired x402.PaymentRequired, isWebBrowser bool, paywallConfig *PaywallConfig, customHTML string) *HTTPResponseInstructions { + if isWebBrowser { + html := s.generatePaywallHTML(paymentRequired, paywallConfig, customHTML) + return &HTTPResponseInstructions{ + Status: 402, + Headers: map[string]string{ + "Content-Type": "text/html", + }, + Body: html, + IsHTML: true, + } + } + + return &HTTPResponseInstructions{ + Status: 402, + Headers: map[string]string{ + "Content-Type": "application/json", + "PAYMENT-REQUIRED": encodePaymentRequiredHeader(paymentRequired), + }, + } +} + +// createSettlementHeaders creates settlement response headers +func (s *x402HTTPResourceService) createSettlementHeaders(response x402.SettleResponse) map[string]string { + return map[string]string{ + "PAYMENT-RESPONSE": encodePaymentResponseHeader(response), + } +} + +// generatePaywallHTML generates HTML paywall for browsers +func (s *x402HTTPResourceService) generatePaywallHTML(paymentRequired x402.PaymentRequired, config *PaywallConfig, customHTML string) string { + if customHTML != "" { + return customHTML + } + + // Calculate display amount (assuming USDC with 6 decimals) + displayAmount := s.getDisplayAmount(paymentRequired) + + resourceDesc := "" + if paymentRequired.Resource != nil { + if paymentRequired.Resource.Description != "" { + resourceDesc = paymentRequired.Resource.Description + } else if paymentRequired.Resource.URL != "" { + resourceDesc = paymentRequired.Resource.URL + } + } + + appLogo := "" + appName := "" + cdpClientKey := "" + testnet := false + + if config != nil { + if config.AppLogo != "" { + appLogo = fmt.Sprintf(`%s`, + html.EscapeString(config.AppLogo), + html.EscapeString(config.AppName)) + } + appName = config.AppName + cdpClientKey = config.CDPClientKey + testnet = config.Testnet + } + + requirementsJSON, _ := json.Marshal(paymentRequired) + + return fmt.Sprintf(` + + + Payment Required + + + + + +
+ %s +

Payment Required

+
+

Resource: %s

+

Amount: $%.2f USDC

+
+
+ +

Loading payment widget...

+
+
+ +`, + appLogo, + html.EscapeString(resourceDesc), + displayAmount, + html.EscapeString(string(requirementsJSON)), + html.EscapeString(cdpClientKey), + html.EscapeString(appName), + testnet, + ) +} + +// getDisplayAmount extracts display amount from payment requirements +func (s *x402HTTPResourceService) getDisplayAmount(paymentRequired x402.PaymentRequired) float64 { + if len(paymentRequired.Accepts) > 0 { + firstReq := paymentRequired.Accepts[0] + // Check if amount field exists + if firstReq.Amount != "" { + // V2 format - parse amount + amount, err := strconv.ParseFloat(firstReq.Amount, 64) + if err == nil { + // Assuming USDC with 6 decimals + return amount / 1000000 + } + } + } + return 0.0 +} + +// ============================================================================ +// Utility Functions +// ============================================================================ + +// parseRoutePattern parses a route pattern like "GET /api/*" +func parseRoutePattern(pattern string) (string, *regexp.Regexp) { + parts := strings.Fields(pattern) + + var verb, path string + if len(parts) == 2 { + verb = strings.ToUpper(parts[0]) + path = parts[1] + } else { + verb = "*" + path = pattern + } + + // Convert pattern to regex + regexPattern := "^" + regexp.QuoteMeta(path) + regexPattern = strings.ReplaceAll(regexPattern, `\*`, `.*?`) + // Handle parameters like [id] + paramRegex := regexp.MustCompile(`\\\[([^\]]+)\\\]`) + regexPattern = paramRegex.ReplaceAllString(regexPattern, `[^/]+`) + regexPattern += "$" + + regex := regexp.MustCompile(regexPattern) + + return verb, regex +} + +// normalizePath normalizes a URL path for matching +func normalizePath(path string) string { + // Remove query string and fragment + if idx := strings.IndexAny(path, "?#"); idx >= 0 { + path = path[:idx] + } + + // Decode URL encoding + if decoded, err := url.PathUnescape(path); err == nil { + path = decoded + } + + // Normalize slashes + path = strings.ReplaceAll(path, `\`, `/`) + // Replace multiple slashes with single slash + multiSlash := regexp.MustCompile(`/+`) + path = multiSlash.ReplaceAllString(path, `/`) + // Remove trailing slash + path = strings.TrimSuffix(path, `/`) + + if path == "" { + path = "/" + } + + return path +} diff --git a/go/http/service_test.go b/go/http/service_test.go new file mode 100644 index 000000000..4935c0ac2 --- /dev/null +++ b/go/http/service_test.go @@ -0,0 +1,587 @@ +package http + +import ( + "context" + "encoding/base64" + "encoding/json" + "strings" + "testing" + + x402 "github.com/coinbase/x402-go/v2" +) + +// Mock HTTP adapter for testing +type mockHTTPAdapter struct { + headers map[string]string + method string + path string + url string + accept string + agent string +} + +func (m *mockHTTPAdapter) GetHeader(name string) string { + if m.headers == nil { + return "" + } + return m.headers[name] +} + +func (m *mockHTTPAdapter) GetMethod() string { + return m.method +} + +func (m *mockHTTPAdapter) GetPath() string { + return m.path +} + +func (m *mockHTTPAdapter) GetURL() string { + return m.url +} + +func (m *mockHTTPAdapter) GetAcceptHeader() string { + return m.accept +} + +func (m *mockHTTPAdapter) GetUserAgent() string { + return m.agent +} + +func TestNewx402HTTPResourceService(t *testing.T) { + routes := RoutesConfig{ + "GET /api": RouteConfig{ + Scheme: "exact", + PayTo: "0xtest", + Price: "$1.00", + Network: "eip155:1", + }, + } + + service := Newx402HTTPResourceService(routes) + if service == nil { + t.Fatal("Expected service to be created") + } + if service.X402ResourceService == nil { + t.Fatal("Expected embedded resource service") + } + if len(service.compiledRoutes) != 1 { + t.Fatal("Expected 1 compiled route") + } +} + +func TestProcessHTTPRequestNoPaymentRequired(t *testing.T) { + ctx := context.Background() + + routes := RoutesConfig{ + "GET /api": RouteConfig{ + Scheme: "exact", + PayTo: "0xtest", + Price: "$1.00", + Network: "eip155:1", + }, + } + + service := Newx402HTTPResourceService(routes) + + // Request to non-protected path + adapter := &mockHTTPAdapter{ + method: "GET", + path: "/public", + url: "http://example.com/public", + } + + reqCtx := HTTPRequestContext{ + Adapter: adapter, + Path: "/public", + Method: "GET", + } + + result := service.ProcessHTTPRequest(ctx, reqCtx, nil) + + if result.Type != ResultNoPaymentRequired { + t.Errorf("Expected no payment required, got %s", result.Type) + } +} + +func TestProcessHTTPRequestPaymentRequired(t *testing.T) { + ctx := context.Background() + + routes := RoutesConfig{ + "GET /api": RouteConfig{ + Scheme: "exact", + PayTo: "0xtest", + Price: "$1.00", + Network: "eip155:1", + Description: "API access", + }, + } + + // Create mock scheme service + mockService := &mockSchemeService{ + scheme: "exact", + parsePrice: func(price x402.Price, network x402.Network) (x402.AssetAmount, error) { + return x402.AssetAmount{ + Asset: "USDC", + Amount: "1000000", + }, nil + }, + } + + // Create mock facilitator client + mockClient := &mockFacilitatorClient{ + supported: func(ctx context.Context) (x402.SupportedResponse, error) { + return x402.SupportedResponse{ + Kinds: []x402.SupportedKind{ + { + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + }, + }, + }, nil + }, + } + + service := Newx402HTTPResourceService( + routes, + x402.WithFacilitatorClient(mockClient), + x402.WithSchemeService("eip155:1", mockService), + ) + service.Initialize(ctx) + + // Request to protected path without payment + adapter := &mockHTTPAdapter{ + method: "GET", + path: "/api", + url: "http://example.com/api", + accept: "application/json", + } + + reqCtx := HTTPRequestContext{ + Adapter: adapter, + Path: "/api", + Method: "GET", + } + + result := service.ProcessHTTPRequest(ctx, reqCtx, nil) + + if result.Type != ResultPaymentError { + t.Errorf("Expected payment error, got %s", result.Type) + } + if result.Response == nil { + t.Fatal("Expected response instructions") + } + if result.Response.Status != 402 { + t.Errorf("Expected status 402, got %d", result.Response.Status) + } + if result.Response.Headers["PAYMENT-REQUIRED"] == "" { + t.Error("Expected PAYMENT-REQUIRED header") + } +} + +func TestProcessHTTPRequestWithBrowser(t *testing.T) { + ctx := context.Background() + + routes := RoutesConfig{ + "*": RouteConfig{ + Scheme: "exact", + PayTo: "0xtest", + Price: "$5.00", + Network: "eip155:1", + Description: "Premium content", + }, + } + + mockService := &mockSchemeService{scheme: "exact"} + mockClient := &mockFacilitatorClient{} + + service := Newx402HTTPResourceService( + routes, + x402.WithFacilitatorClient(mockClient), + x402.WithSchemeService("eip155:1", mockService), + ) + service.Initialize(ctx) + + // Browser request + adapter := &mockHTTPAdapter{ + method: "GET", + path: "/content", + url: "http://example.com/content", + accept: "text/html", + agent: "Mozilla/5.0", + } + + reqCtx := HTTPRequestContext{ + Adapter: adapter, + Path: "/content", + Method: "GET", + } + + paywallConfig := &PaywallConfig{ + AppName: "Test App", + CDPClientKey: "test-key", + } + + result := service.ProcessHTTPRequest(ctx, reqCtx, paywallConfig) + + if result.Type != ResultPaymentError { + t.Errorf("Expected payment error, got %s", result.Type) + } + if result.Response == nil { + t.Fatal("Expected response instructions") + } + if !result.Response.IsHTML { + t.Error("Expected HTML response") + } + if result.Response.Headers["Content-Type"] != "text/html" { + t.Error("Expected text/html content type") + } + + // Check HTML contains expected elements + html := result.Response.Body.(string) + if !strings.Contains(html, "Payment Required") { + t.Error("Expected 'Payment Required' in HTML") + } + if !strings.Contains(html, "Test App") { + t.Error("Expected app name in HTML") + } + if !strings.Contains(html, "test-key") { + t.Error("Expected CDP client key in HTML") + } +} + +func TestProcessHTTPRequestWithPaymentVerified(t *testing.T) { + ctx := context.Background() + + routes := RoutesConfig{ + "POST /api": RouteConfig{ + Scheme: "exact", + PayTo: "0xtest", + Price: "$1.00", + Network: "eip155:1", + }, + } + + mockService := &mockSchemeService{ + scheme: "exact", + enhanceReqs: func(ctx context.Context, base x402.PaymentRequirements, supported x402.SupportedKind, extensions []string) (x402.PaymentRequirements, error) { + // Make sure the enhanced requirements match what we'll send + base.PayTo = "0xtest" + return base, nil + }, + } + mockClient := &mockFacilitatorClient{ + verify: func(ctx context.Context, payload x402.PaymentPayload, requirements x402.PaymentRequirements) (x402.VerifyResponse, error) { + return x402.VerifyResponse{ + IsValid: true, + Payer: "0xpayer", + }, nil + }, + } + + service := Newx402HTTPResourceService( + routes, + x402.WithFacilitatorClient(mockClient), + x402.WithSchemeService("eip155:1", mockService), + ) + service.Initialize(ctx) + + // Create payment payload + // First build the actual requirements + builtReqs, _ := service.BuildPaymentRequirements(ctx, x402.ResourceConfig{ + Scheme: "exact", + PayTo: "0xtest", + Price: "$1.00", + Network: "eip155:1", + }) + + paymentPayload := x402.PaymentPayload{ + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + Payload: map[string]interface{}{"sig": "test"}, + Accepted: builtReqs[0], // Use the actual built requirements + } + + payloadJSON, _ := json.Marshal(paymentPayload) + encoded := base64.StdEncoding.EncodeToString(payloadJSON) + + // Request with payment + adapter := &mockHTTPAdapter{ + method: "POST", + path: "/api", + url: "http://example.com/api", + headers: map[string]string{ + "PAYMENT-SIGNATURE": encoded, + }, + } + + reqCtx := HTTPRequestContext{ + Adapter: adapter, + Path: "/api", + Method: "POST", + } + + result := service.ProcessHTTPRequest(ctx, reqCtx, nil) + + if result.Type != ResultPaymentVerified { + t.Errorf("Expected payment verified, got %s", result.Type) + } + if result.PaymentPayload == nil { + t.Error("Expected payment payload") + } + if result.PaymentRequirements == nil { + t.Error("Expected payment requirements") + } +} + +func TestProcessSettlement(t *testing.T) { + ctx := context.Background() + + mockClient := &mockFacilitatorClient{ + settle: func(ctx context.Context, payload x402.PaymentPayload, requirements x402.PaymentRequirements) (x402.SettleResponse, error) { + return x402.SettleResponse{ + Success: true, + Transaction: "0xtx", + Payer: "0xpayer", + }, nil + }, + } + + service := Newx402HTTPResourceService( + RoutesConfig{}, + x402.WithFacilitatorClient(mockClient), + ) + service.Initialize(ctx) + + payload := x402.PaymentPayload{ + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + Payload: map[string]interface{}{}, + } + + requirements := x402.PaymentRequirements{ + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xtest", + } + + // Test successful response (should settle) + headers, err := service.ProcessSettlement(ctx, payload, requirements, 200) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if headers == nil { + t.Fatal("Expected settlement headers") + } + if headers["PAYMENT-RESPONSE"] == "" { + t.Error("Expected PAYMENT-RESPONSE header") + } + + // Test failed response (should not settle) + headers, err = service.ProcessSettlement(ctx, payload, requirements, 400) + if err != nil { + t.Fatalf("Unexpected error for 400: %v", err) + } + if headers != nil { + t.Error("Expected no headers for failed response") + } +} + +func TestParseRoutePattern(t *testing.T) { + tests := []struct { + pattern string + expectVerb string + testPath string + shouldMatch bool + }{ + { + pattern: "GET /api", + expectVerb: "GET", + testPath: "/api", + shouldMatch: true, + }, + { + pattern: "POST /api/*", + expectVerb: "POST", + testPath: "/api/users", + shouldMatch: true, + }, + { + pattern: "/public", + expectVerb: "*", + testPath: "/public", + shouldMatch: true, + }, + { + pattern: "*", + expectVerb: "*", + testPath: "/anything", + shouldMatch: true, + }, + { + pattern: "GET /api/[id]", + expectVerb: "GET", + testPath: "/api/123", + shouldMatch: true, + }, + } + + for _, tt := range tests { + t.Run(tt.pattern, func(t *testing.T) { + verb, regex := parseRoutePattern(tt.pattern) + + if verb != tt.expectVerb { + t.Errorf("Expected verb %s, got %s", tt.expectVerb, verb) + } + + normalized := normalizePath(tt.testPath) + if regex.MatchString(normalized) != tt.shouldMatch { + t.Errorf("Expected match=%v for path %s", tt.shouldMatch, tt.testPath) + } + }) + } +} + +func TestNormalizePath(t *testing.T) { + tests := []struct { + input string + expected string + }{ + {"/api", "/api"}, + {"/api/", "/api"}, + {"/api//users", "/api/users"}, + {"/api?query=1", "/api"}, + {"/api#fragment", "/api"}, + {"/api%20space", "/api space"}, + {"", "/"}, + } + + for _, tt := range tests { + t.Run(tt.input, func(t *testing.T) { + result := normalizePath(tt.input) + if result != tt.expected { + t.Errorf("Expected %s, got %s", tt.expected, result) + } + }) + } +} + +func TestGetDisplayAmount(t *testing.T) { + service := Newx402HTTPResourceService(RoutesConfig{}) + + tests := []struct { + name string + required x402.PaymentRequired + expected float64 + }{ + { + name: "USDC with 6 decimals", + required: x402.PaymentRequired{ + Accepts: []x402.PaymentRequirements{ + {Amount: "5000000"}, + }, + }, + expected: 5.0, + }, + { + name: "Small amount", + required: x402.PaymentRequired{ + Accepts: []x402.PaymentRequirements{ + {Amount: "100000"}, + }, + }, + expected: 0.1, + }, + { + name: "Invalid amount", + required: x402.PaymentRequired{ + Accepts: []x402.PaymentRequirements{ + {Amount: "not-a-number"}, + }, + }, + expected: 0.0, + }, + { + name: "No requirements", + required: x402.PaymentRequired{}, + expected: 0.0, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := service.getDisplayAmount(tt.required) + if result != tt.expected { + t.Errorf("Expected %f, got %f", tt.expected, result) + } + }) + } +} + +// Mock scheme service for testing +type mockSchemeService struct { + scheme string + parsePrice func(price x402.Price, network x402.Network) (x402.AssetAmount, error) + enhanceReqs func(ctx context.Context, base x402.PaymentRequirements, supported x402.SupportedKind, extensions []string) (x402.PaymentRequirements, error) +} + +func (m *mockSchemeService) Scheme() string { + return m.scheme +} + +func (m *mockSchemeService) ParsePrice(price x402.Price, network x402.Network) (x402.AssetAmount, error) { + if m.parsePrice != nil { + return m.parsePrice(price, network) + } + return x402.AssetAmount{ + Asset: "USDC", + Amount: "1000000", + }, nil +} + +func (m *mockSchemeService) EnhancePaymentRequirements(ctx context.Context, base x402.PaymentRequirements, supported x402.SupportedKind, extensions []string) (x402.PaymentRequirements, error) { + if m.enhanceReqs != nil { + return m.enhanceReqs(ctx, base, supported, extensions) + } + return base, nil +} + +// Mock facilitator client +type mockFacilitatorClient struct { + verify func(ctx context.Context, payload x402.PaymentPayload, requirements x402.PaymentRequirements) (x402.VerifyResponse, error) + settle func(ctx context.Context, payload x402.PaymentPayload, requirements x402.PaymentRequirements) (x402.SettleResponse, error) + supported func(ctx context.Context) (x402.SupportedResponse, error) +} + +func (m *mockFacilitatorClient) Verify(ctx context.Context, payload x402.PaymentPayload, requirements x402.PaymentRequirements) (x402.VerifyResponse, error) { + if m.verify != nil { + return m.verify(ctx, payload, requirements) + } + return x402.VerifyResponse{IsValid: true}, nil +} + +func (m *mockFacilitatorClient) Settle(ctx context.Context, payload x402.PaymentPayload, requirements x402.PaymentRequirements) (x402.SettleResponse, error) { + if m.settle != nil { + return m.settle(ctx, payload, requirements) + } + return x402.SettleResponse{Success: true}, nil +} + +func (m *mockFacilitatorClient) GetSupported(ctx context.Context) (x402.SupportedResponse, error) { + if m.supported != nil { + return m.supported(ctx) + } + return x402.SupportedResponse{ + Kinds: []x402.SupportedKind{ + {X402Version: 2, Scheme: "exact", Network: "eip155:1"}, + }, + }, nil +} + +func (m *mockFacilitatorClient) Identifier() string { + return "mock" +} diff --git a/go/interfaces.go b/go/interfaces.go new file mode 100644 index 000000000..580d481dc --- /dev/null +++ b/go/interfaces.go @@ -0,0 +1,57 @@ +package x402 + +import "context" + +// SchemeNetworkClient is implemented by client-side payment mechanisms +// This interface is used by clients who sign/create payments +type SchemeNetworkClient interface { + // Scheme returns the payment scheme identifier (e.g., "exact") + Scheme() string + + // CreatePaymentPayload creates a signed payment for the given requirements + // This is where wallet/signer interaction happens + CreatePaymentPayload(ctx context.Context, version int, requirements PaymentRequirements) (PaymentPayload, error) +} + +// SchemeNetworkFacilitator is implemented by facilitator-side payment mechanisms +// This interface is used by facilitators who verify and settle payments +type SchemeNetworkFacilitator interface { + // Scheme returns the payment scheme identifier (e.g., "exact") + Scheme() string + + // Verify checks if a payment is valid without executing it + Verify(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (VerifyResponse, error) + + // Settle executes the payment on-chain + Settle(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (SettleResponse, error) +} + +// SchemeNetworkService is implemented by server-side payment mechanisms +// This interface is used by servers who create payment requirements +type SchemeNetworkService interface { + // Scheme returns the payment scheme identifier (e.g., "exact") + Scheme() string + + // ParsePrice converts a user-friendly price to asset/amount format + ParsePrice(price Price, network Network) (AssetAmount, error) + + // EnhancePaymentRequirements adds scheme-specific details to requirements + EnhancePaymentRequirements( + ctx context.Context, + requirements PaymentRequirements, + supportedKind SupportedKind, + extensions []string, + ) (PaymentRequirements, error) +} + +// FacilitatorClient interface for services to interact with facilitators +type FacilitatorClient interface { + // Verify a payment against requirements + Verify(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (VerifyResponse, error) + + // Settle a payment + Settle(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (SettleResponse, error) + + // Get supported payment kinds + GetSupported(ctx context.Context) (SupportedResponse, error) +} diff --git a/go/legacy/README.md b/go/legacy/README.md new file mode 100644 index 000000000..851fd5f2e --- /dev/null +++ b/go/legacy/README.md @@ -0,0 +1,47 @@ +# Go x402 + +## Installation + +```bash +go get github.com/coinbase/x402/go +``` + +## Usage + +### Accepting x402 Payments with a [Gin](https://github.com/gin-gonic/gin) Resource Server + +```go +package main + +import ( + "math/big" + + x402gin "github.com/coinbase/x402/go/pkg/gin" + "github.com/gin-gonic/gin" +) + +func main() { + r := gin.Default() + + facilitatorConfig := &types.FacilitatorConfig{ + URL: "http://localhost:3000", + } + + r.GET( + "/joke", + x402gin.PaymentMiddleware( + big.NewFloat(0.0001), + "0x209693Bc6afc0C5328bA36FaF03C514EF312287C", + x402gin.WithFacilitatorConfig(facilitatorConfig), + x402gin.WithResource("http://localhost:4021/joke"), + ), + func(c *gin.Context) { + c.JSON(200, gin.H{ + "joke": "Why do programmers prefer dark mode? Because light attracts bugs!", + }) + }, + ) + + r.Run(":4021") // Start the server on 0.0.0.0:4021 (for windows "localhost:4021") +} +``` diff --git a/go/bin/README.md b/go/legacy/bin/README.md similarity index 100% rename from go/bin/README.md rename to go/legacy/bin/README.md diff --git a/go/bin/example_config.json b/go/legacy/bin/example_config.json similarity index 100% rename from go/bin/example_config.json rename to go/legacy/bin/example_config.json diff --git a/go/bin/proxy_demo.go b/go/legacy/bin/proxy_demo.go similarity index 100% rename from go/bin/proxy_demo.go rename to go/legacy/bin/proxy_demo.go diff --git a/go/bin/simple_config.json b/go/legacy/bin/simple_config.json similarity index 100% rename from go/bin/simple_config.json rename to go/legacy/bin/simple_config.json diff --git a/go/examples/mainnet/.env-local b/go/legacy/examples/mainnet/.env-local similarity index 100% rename from go/examples/mainnet/.env-local rename to go/legacy/examples/mainnet/.env-local diff --git a/go/examples/mainnet/README.md b/go/legacy/examples/mainnet/README.md similarity index 100% rename from go/examples/mainnet/README.md rename to go/legacy/examples/mainnet/README.md diff --git a/go/examples/mainnet/mainnet.go b/go/legacy/examples/mainnet/mainnet.go similarity index 100% rename from go/examples/mainnet/mainnet.go rename to go/legacy/examples/mainnet/mainnet.go diff --git a/go/examples/server/resource.go b/go/legacy/examples/server/resource.go similarity index 100% rename from go/examples/server/resource.go rename to go/legacy/examples/server/resource.go diff --git a/go/legacy/go.mod b/go/legacy/go.mod new file mode 100644 index 000000000..67dee8d4b --- /dev/null +++ b/go/legacy/go.mod @@ -0,0 +1,45 @@ +module github.com/coinbase/x402/go + +go 1.23.3 + +require ( + github.com/coinbase/cdp-sdk/go v0.0.0-20250506223104-85d38372d771 + github.com/gin-gonic/gin v1.10.0 + github.com/joho/godotenv v1.5.1 + github.com/stretchr/testify v1.10.0 +) + +require ( + github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect + github.com/bytedance/sonic v1.13.2 // indirect + github.com/bytedance/sonic/loader v0.2.4 // indirect + github.com/cloudwego/base64x v0.1.5 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/gabriel-vasile/mimetype v1.4.8 // indirect + github.com/gin-contrib/sse v1.0.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.26.0 // indirect + github.com/goccy/go-json v0.10.5 // indirect + github.com/golang-jwt/jwt/v5 v5.2.2 // indirect + github.com/google/uuid v1.5.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.10 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/oapi-codegen/runtime v1.1.1 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + golang.org/x/arch v0.15.0 // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/net v0.38.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/text v0.23.0 // indirect + google.golang.org/protobuf v1.36.6 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go/legacy/go.sum b/go/legacy/go.sum new file mode 100644 index 000000000..32422017a --- /dev/null +++ b/go/legacy/go.sum @@ -0,0 +1,110 @@ +github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= +github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= +github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= +github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= +github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ= +github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= +github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/coinbase/cdp-sdk/go v0.0.0-20250506223104-85d38372d771 h1:zFdgvx+jMCTkrOUTUD2Xmpk4vSusnpGqE90Gl37+WLQ= +github.com/coinbase/cdp-sdk/go v0.0.0-20250506223104-85d38372d771/go.mod h1:7SCUyseVQvmT158f23xvVghYF7dYxypj0sw+558F+7g= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= +github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= +github.com/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E= +github.com/gin-contrib/sse v1.0.0/go.mod h1:zNuFdwarAygJBht0NTKiSi3jRf6RbqeILZ9Sp6Slhe0= +github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= +github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k= +github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= +github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= +github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= +github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= +github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro= +github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= +github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +golang.org/x/arch v0.15.0 h1:QtOrQd0bTUnhNVNndMpLHNWrDmYzZ2KDqSrEymqInZw= +golang.org/x/arch v0.15.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= diff --git a/go/pkg/coinbasefacilitator/cdp.go b/go/legacy/pkg/coinbasefacilitator/cdp.go similarity index 100% rename from go/pkg/coinbasefacilitator/cdp.go rename to go/legacy/pkg/coinbasefacilitator/cdp.go diff --git a/go/pkg/coinbasefacilitator/facilitator.go b/go/legacy/pkg/coinbasefacilitator/facilitator.go similarity index 100% rename from go/pkg/coinbasefacilitator/facilitator.go rename to go/legacy/pkg/coinbasefacilitator/facilitator.go diff --git a/go/pkg/facilitatorclient/facilitatorclient.go b/go/legacy/pkg/facilitatorclient/facilitatorclient.go similarity index 100% rename from go/pkg/facilitatorclient/facilitatorclient.go rename to go/legacy/pkg/facilitatorclient/facilitatorclient.go diff --git a/go/pkg/facilitatorclient/facilitatorclient_test.go b/go/legacy/pkg/facilitatorclient/facilitatorclient_test.go similarity index 100% rename from go/pkg/facilitatorclient/facilitatorclient_test.go rename to go/legacy/pkg/facilitatorclient/facilitatorclient_test.go diff --git a/go/pkg/gin/middleware.go b/go/legacy/pkg/gin/middleware.go similarity index 97% rename from go/pkg/gin/middleware.go rename to go/legacy/pkg/gin/middleware.go index af978ecdd..79634ea5c 100644 --- a/go/pkg/gin/middleware.go +++ b/go/legacy/pkg/gin/middleware.go @@ -190,9 +190,13 @@ func PaymentMiddleware(amount *big.Float, address string, opts ...Options) gin.H } if !response.IsValid { - fmt.Println("Invalid payment: ", response.InvalidReason) + invalidReason := "Unknown error" + if response.InvalidReason != nil { + invalidReason = *response.InvalidReason + } + fmt.Println("Invalid payment:", invalidReason) c.AbortWithStatusJSON(http.StatusPaymentRequired, gin.H{ - "error": response.InvalidReason, + "error": invalidReason, "accepts": []*types.PaymentRequirements{paymentRequirements}, "x402Version": x402Version, }) diff --git a/go/pkg/gin/middleware_test.go b/go/legacy/pkg/gin/middleware_test.go similarity index 100% rename from go/pkg/gin/middleware_test.go rename to go/legacy/pkg/gin/middleware_test.go diff --git a/go/pkg/types/types.go b/go/legacy/pkg/types/types.go similarity index 100% rename from go/pkg/types/types.go rename to go/legacy/pkg/types/types.go diff --git a/go/pkg/types/version.go b/go/legacy/pkg/types/version.go similarity index 100% rename from go/pkg/types/version.go rename to go/legacy/pkg/types/version.go diff --git a/go/mechanisms/evm/README.md b/go/mechanisms/evm/README.md new file mode 100644 index 000000000..6656f9dc7 --- /dev/null +++ b/go/mechanisms/evm/README.md @@ -0,0 +1,167 @@ +# EVM Mechanism for x402 (V2) + +This package provides V2 EVM blockchain support for the x402 payment protocol. It implements the `exact` payment scheme using EIP-3009 TransferWithAuthorization. + +**Note**: This is the V2 implementation which supports x402 protocol version 2. For V1 support, use the `v1` subpackage. + +## Features + +- **EIP-3009 Support**: Gasless token transfers using TransferWithAuthorization +- **EIP-712 Signing**: Structured data signing for secure authorization +- **Multi-Network Support**: Base, Base Sepolia, Ethereum Mainnet +- **USDC Integration**: Default support for USDC stablecoin +- **Modular Design**: Clean separation between client, facilitator, and service components + +## Installation + +```go +// For V2 (default, recommended) +import "github.com/coinbase/x402-go/v2/mechanisms/evm" + +// For V1 (legacy support) +import evmv1 "github.com/coinbase/x402-go/v2/mechanisms/evm/v1" +``` + +## Usage + +### Client-Side (Payment Creation) + +```go +import ( + x402 "github.com/coinbase/x402-go/v2" + "github.com/coinbase/x402-go/v2/mechanisms/evm" +) + +// Implement the ClientEvmSigner interface +type mySigner struct { + // Your wallet implementation +} + +func (s *mySigner) Address() string { + return "0x..." // Your address +} + +func (s *mySigner) SignTypedData(domain evm.TypedDataDomain, types map[string][]evm.TypedDataField, primaryType string, message map[string]interface{}) ([]byte, error) { + // Your EIP-712 signing implementation +} + +// Create payment +signer := &mySigner{} +client := x402.Newx402Client() +evm.RegisterClient(client, signer, "base") + +requirements := x402.PaymentRequirements{ + Network: "base", + Asset: "USDC", + PayTo: "0xrecipient", + Amount: "1.50", // $1.50 USDC +} + +payload, err := client.CreatePaymentPayload(ctx, 2, requirements) +``` + +### Facilitator-Side (Verification & Settlement) + +```go +// Implement the FacilitatorEvmSigner interface +type myFacilitatorSigner struct { + // Your blockchain client implementation +} + +// Create facilitator +facilitator := x402.Newx402Facilitator() +signer := &myFacilitatorSigner{} +evm.RegisterFacilitator(facilitator, signer, "base") + +// Verify payment +verifyResp, err := facilitator.Verify(ctx, payload, requirements) +if verifyResp.IsValid { + // Payment is valid + fmt.Printf("Payer: %s\n", verifyResp.Payer) +} + +// Settle payment on-chain +settleResp, err := facilitator.Settle(ctx, payload, requirements) +if settleResp.Success { + fmt.Printf("Transaction: %s\n", settleResp.Transaction) +} +``` + +### Service-Side (Price Parsing & Requirements) + +```go +// Create service with EVM support +service := x402.Newx402ResourceService( + evm.RegisterService("base", "base-sepolia")..., +) + +// Parse price to asset amount +assetAmount, err := evmService.ParsePrice("$1.50", "base") +// Returns: { Asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", Amount: "1500000" } + +// Enhance payment requirements +enhanced, err := evmService.EnhancePaymentRequirements( + ctx, + requirements, + supportedKind, + []string{"customField"}, +) +``` + +## Supported Networks + +| Network | Chain ID | USDC Address | Network String | +|---------|----------|--------------|----------------| +| Base Mainnet | 8453 | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 | `base`, `base-mainnet`, `eip155:8453` | +| Base Sepolia | 84532 | 0x036CbD53842c5426634e7929541eC2318f3dCF7e | `base-sepolia`, `eip155:84532` | +| Ethereum Mainnet | 1 | 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 | `eip155:1` | + +## EIP-3009 Authorization Structure + +The exact payment scheme uses EIP-3009 TransferWithAuthorization with the following structure: + +```go +type ExactEIP3009Authorization struct { + From string // Token holder address + To string // Recipient address + Value string // Amount in smallest unit (e.g., 1000000 = 1 USDC) + ValidAfter string // Unix timestamp + ValidBefore string // Unix timestamp + Nonce string // 32-byte unique nonce +} +``` + +## Testing + +```bash +cd go/mechanisms/evm +go test -v +``` + +## Dependencies + +- `github.com/ethereum/go-ethereum`: Ethereum Go implementation +- `github.com/coinbase/x402-go/v2`: Core x402 protocol + +## Version Differences + +### V2 (This Package) +- Supports x402 protocol version 2 +- No buffer on `validAfter` (can be used immediately) +- Default validity window of 1 hour +- Enhanced price parsing with multiple format support + +### V1 (v1 Subpackage) +- Supports x402 protocol version 1 only +- 10-minute buffer subtracted from `validAfter` +- Default validity window of 10 minutes +- Simpler price parsing logic + +For backward compatibility with existing V1 integrations, use: +```go +import evmv1 "github.com/coinbase/x402-go/v2/mechanisms/evm/v1" +``` + +## License + +See the main x402 repository for license information. diff --git a/go/mechanisms/evm/client.go b/go/mechanisms/evm/client.go new file mode 100644 index 000000000..c70c85fe8 --- /dev/null +++ b/go/mechanisms/evm/client.go @@ -0,0 +1,176 @@ +package evm + +import ( + "context" + "fmt" + "math/big" + "time" + + x402 "github.com/coinbase/x402-go/v2" +) + +// ExactEvmClient implements the SchemeNetworkClient interface for EVM exact payments (V2) +type ExactEvmClient struct { + signer ClientEvmSigner +} + +// NewExactEvmClient creates a new ExactEvmClient +func NewExactEvmClient(signer ClientEvmSigner) *ExactEvmClient { + return &ExactEvmClient{ + signer: signer, + } +} + +// Scheme returns the scheme identifier +func (c *ExactEvmClient) Scheme() string { + return SchemeExact +} + +// CreatePaymentPayload creates a payment payload for the exact scheme (V2) +func (c *ExactEvmClient) CreatePaymentPayload( + ctx context.Context, + version int, + requirements x402.PaymentRequirements, +) (x402.PaymentPayload, error) { + // V2 specific: only handle version 2 + if version != 2 { + return x402.PaymentPayload{}, fmt.Errorf("v2 only supports x402 version 2") + } + + // Validate network + networkStr := string(requirements.Network) + if !IsValidNetwork(networkStr) { + return x402.PaymentPayload{}, fmt.Errorf("unsupported network: %s", requirements.Network) + } + + // Get network configuration + config, err := GetNetworkConfig(networkStr) + if err != nil { + return x402.PaymentPayload{}, err + } + + // Get asset info + assetInfo, err := GetAssetInfo(networkStr, requirements.Asset) + if err != nil { + return x402.PaymentPayload{}, err + } + + // Requirements.Amount is already in the smallest unit + value, ok := new(big.Int).SetString(requirements.Amount, 10) + if !ok { + return x402.PaymentPayload{}, fmt.Errorf("invalid amount: %s", requirements.Amount) + } + + // Create nonce + nonce, err := CreateNonce() + if err != nil { + return x402.PaymentPayload{}, err + } + + // V2 specific: No buffer on validAfter (can use immediately) + validAfter, validBefore := CreateValidityWindow(time.Hour) + + // Extract extra fields for EIP-3009 + tokenName := assetInfo.Name + tokenVersion := assetInfo.Version + if requirements.Extra != nil { + if name, ok := requirements.Extra["name"].(string); ok { + tokenName = name + } + if version, ok := requirements.Extra["version"].(string); ok { + tokenVersion = version + } + } + + // Create authorization + authorization := ExactEIP3009Authorization{ + From: c.signer.Address(), + To: requirements.PayTo, + Value: value.String(), + ValidAfter: validAfter.String(), + ValidBefore: validBefore.String(), + Nonce: nonce, + } + + // Sign the authorization + signature, err := c.signAuthorization(ctx, authorization, config.ChainID, assetInfo.Address, tokenName, tokenVersion) + if err != nil { + return x402.PaymentPayload{}, fmt.Errorf("failed to sign authorization: %w", err) + } + + // Create payload + evmPayload := &ExactEIP3009Payload{ + Signature: BytesToHex(signature), + Authorization: authorization, + } + + // Convert to PaymentPayload + payload := x402.PaymentPayload{ + X402Version: version, + Scheme: SchemeExact, + Network: requirements.Network, + Payload: evmPayload.ToMap(), + } + + // V2 specific: Set Accepted field + if version == 2 { + payload.Accepted = requirements + } + + return payload, nil +} + +// signAuthorization signs the EIP-3009 authorization using EIP-712 +func (c *ExactEvmClient) signAuthorization( + ctx context.Context, + authorization ExactEIP3009Authorization, + chainID *big.Int, + verifyingContract string, + tokenName string, + tokenVersion string, +) ([]byte, error) { + // Create EIP-712 domain + domain := TypedDataDomain{ + Name: tokenName, + Version: tokenVersion, + ChainID: chainID, + VerifyingContract: verifyingContract, + } + + // Define EIP-712 types + types := map[string][]TypedDataField{ + "EIP712Domain": { + {Name: "name", Type: "string"}, + {Name: "version", Type: "string"}, + {Name: "chainId", Type: "uint256"}, + {Name: "verifyingContract", Type: "address"}, + }, + "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"}, + }, + } + + // Parse values for message + value, _ := new(big.Int).SetString(authorization.Value, 10) + validAfter, _ := new(big.Int).SetString(authorization.ValidAfter, 10) + validBefore, _ := new(big.Int).SetString(authorization.ValidBefore, 10) + nonceBytes, _ := HexToBytes(authorization.Nonce) + + // Create message + message := map[string]interface{}{ + "from": authorization.From, + "to": authorization.To, + "value": value, + "validAfter": validAfter, + "validBefore": validBefore, + "nonce": nonceBytes, + } + + // Sign the typed data + return c.signer.SignTypedData(domain, types, "TransferWithAuthorization", message) +} diff --git a/go/mechanisms/evm/constants.go b/go/mechanisms/evm/constants.go new file mode 100644 index 000000000..a0c9702ca --- /dev/null +++ b/go/mechanisms/evm/constants.go @@ -0,0 +1,169 @@ +package evm + +import ( + "math/big" +) + +const ( + // Scheme identifier + SchemeExact = "exact" + + // Default token decimals for USDC + DefaultDecimals = 6 + + // EIP-3009 function names + FunctionTransferWithAuthorization = "transferWithAuthorization" + FunctionReceiveWithAuthorization = "receiveWithAuthorization" + FunctionAuthorizationState = "authorizationState" + + // Transaction status + TxStatusSuccess = 1 + TxStatusFailed = 0 + + // Default validity period (1 hour) + DefaultValidityPeriod = 3600 // seconds +) + +var ( + // Network chain IDs + ChainIDMainnet = big.NewInt(1) + ChainIDBase = big.NewInt(8453) + ChainIDBaseSepolia = big.NewInt(84532) + + // Network configurations + NetworkConfigs = map[string]NetworkConfig{ + "eip155:1": { + ChainID: ChainIDMainnet, + DefaultAsset: AssetInfo{ + Address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC on Ethereum mainnet + Name: "USD Coin", + Version: "2", + Decimals: DefaultDecimals, + }, + SupportedAssets: map[string]AssetInfo{ + "USDC": { + Address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + Name: "USD Coin", + Version: "2", + Decimals: DefaultDecimals, + }, + }, + }, + "eip155:8453": { + ChainID: ChainIDBase, + DefaultAsset: AssetInfo{ + Address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC on Base + Name: "USD Coin", + Version: "2", + Decimals: DefaultDecimals, + }, + SupportedAssets: map[string]AssetInfo{ + "USDC": { + Address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + Name: "USD Coin", + Version: "2", + Decimals: DefaultDecimals, + }, + }, + }, + "base": { + ChainID: ChainIDBase, + DefaultAsset: AssetInfo{ + Address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + Name: "USD Coin", + Version: "2", + Decimals: DefaultDecimals, + }, + SupportedAssets: map[string]AssetInfo{ + "USDC": { + Address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + Name: "USD Coin", + Version: "2", + Decimals: DefaultDecimals, + }, + }, + }, + "base-mainnet": { + ChainID: ChainIDBase, + DefaultAsset: AssetInfo{ + Address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + Name: "USD Coin", + Version: "2", + Decimals: DefaultDecimals, + }, + SupportedAssets: map[string]AssetInfo{ + "USDC": { + Address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + Name: "USD Coin", + Version: "2", + Decimals: DefaultDecimals, + }, + }, + }, + "eip155:84532": { + ChainID: ChainIDBaseSepolia, + DefaultAsset: AssetInfo{ + Address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", // USDC on Base Sepolia + Name: "USDC", + Version: "2", + Decimals: DefaultDecimals, + }, + SupportedAssets: map[string]AssetInfo{ + "USDC": { + Address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", + Name: "USDC", + Version: "2", + Decimals: DefaultDecimals, + }, + }, + }, + "base-sepolia": { + ChainID: ChainIDBaseSepolia, + DefaultAsset: AssetInfo{ + Address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", + Name: "USDC", + Version: "2", + Decimals: DefaultDecimals, + }, + SupportedAssets: map[string]AssetInfo{ + "USDC": { + Address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", + Name: "USDC", + Version: "2", + Decimals: DefaultDecimals, + }, + }, + }, + } + + // EIP-3009 ABI for transferWithAuthorization + TransferWithAuthorizationABI = []byte(`[ + { + "inputs": [ + {"name": "from", "type": "address"}, + {"name": "to", "type": "address"}, + {"name": "value", "type": "uint256"}, + {"name": "validAfter", "type": "uint256"}, + {"name": "validBefore", "type": "uint256"}, + {"name": "nonce", "type": "bytes32"}, + {"name": "v", "type": "uint8"}, + {"name": "r", "type": "bytes32"}, + {"name": "s", "type": "bytes32"} + ], + "name": "transferWithAuthorization", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + {"name": "authorizer", "type": "address"}, + {"name": "nonce", "type": "bytes32"} + ], + "name": "authorizationState", + "outputs": [{"name": "", "type": "bool"}], + "stateMutability": "view", + "type": "function" + } + ]`) +) diff --git a/go/mechanisms/evm/evm.go b/go/mechanisms/evm/evm.go new file mode 100644 index 000000000..830596d10 --- /dev/null +++ b/go/mechanisms/evm/evm.go @@ -0,0 +1,129 @@ +// Package evm provides V2 EVM blockchain support for the x402 payment protocol. +// It implements the exact payment scheme using EIP-3009 TransferWithAuthorization. +// For V1 support, use the v1 subpackage. +package evm + +import ( + "context" + + x402 "github.com/coinbase/x402-go/v2" +) + +// Register registers all V2 EVM mechanism implementations with the x402 client, facilitator, and service +func Register( + client *x402.X402Client, + facilitator *x402.X402Facilitator, + service *x402.X402ResourceService, + signer interface{}, + networks []string, +) error { + // Determine which components to register based on the signer type + var clientSigner ClientEvmSigner + var facilitatorSigner FacilitatorEvmSigner + + // Try to cast signer to the appropriate interfaces + if s, ok := signer.(ClientEvmSigner); ok { + clientSigner = s + } + if s, ok := signer.(FacilitatorEvmSigner); ok { + facilitatorSigner = s + } + + // If no specific networks provided, use all supported networks + if len(networks) == 0 { + for network := range NetworkConfigs { + networks = append(networks, network) + } + } + + // Register with client if we have a client signer + if client != nil && clientSigner != nil { + evmClient := NewExactEvmClient(clientSigner) + for _, network := range networks { + if IsValidNetwork(network) { + client.RegisterScheme(x402.Network(network), evmClient) + } + } + } + + // Register with facilitator if we have a facilitator signer + if facilitator != nil && facilitatorSigner != nil { + evmFacilitator := NewExactEvmFacilitator(facilitatorSigner) + for _, network := range networks { + if IsValidNetwork(network) { + facilitator.RegisterScheme(x402.Network(network), evmFacilitator) + } + } + } + + // Register with service (no signer needed) + // Note: Service registration is done via RegisterService() which returns options + if service != nil { + // Service options should be passed during service creation + } + + return nil +} + +// RegisterClient registers the V2 EVM client implementation +func RegisterClient(client *x402.X402Client, signer ClientEvmSigner, networks ...string) error { + return Register(client, nil, nil, signer, networks) +} + +// RegisterFacilitator registers the V2 EVM facilitator implementation +func RegisterFacilitator(facilitator *x402.X402Facilitator, signer FacilitatorEvmSigner, networks ...string) error { + return Register(nil, facilitator, nil, signer, networks) +} + +// RegisterService returns the option to register the V2 EVM service implementation +func RegisterService(networks ...string) []x402.ResourceServiceOption { + evmService := NewExactEvmService() + opts := []x402.ResourceServiceOption{} + + if len(networks) == 0 { + for network := range NetworkConfigs { + networks = append(networks, network) + } + } + + for _, network := range networks { + if IsValidNetwork(network) { + opts = append(opts, x402.WithSchemeService(x402.Network(network), evmService)) + } + } + + return opts +} + +// CreateExactPayload is a helper to create a V2 exact EVM payment payload +func CreateExactPayload( + ctx context.Context, + signer ClientEvmSigner, + requirements x402.PaymentRequirements, + version int, +) (x402.PaymentPayload, error) { + client := NewExactEvmClient(signer) + return client.CreatePaymentPayload(ctx, version, requirements) +} + +// VerifyExactPayload is a helper to verify a V2 exact EVM payment payload +func VerifyExactPayload( + ctx context.Context, + signer FacilitatorEvmSigner, + payload x402.PaymentPayload, + requirements x402.PaymentRequirements, +) (x402.VerifyResponse, error) { + facilitator := NewExactEvmFacilitator(signer) + return facilitator.Verify(ctx, payload, requirements) +} + +// SettleExactPayload is a helper to settle a V2 exact EVM payment payload +func SettleExactPayload( + ctx context.Context, + signer FacilitatorEvmSigner, + payload x402.PaymentPayload, + requirements x402.PaymentRequirements, +) (x402.SettleResponse, error) { + facilitator := NewExactEvmFacilitator(signer) + return facilitator.Settle(ctx, payload, requirements) +} diff --git a/go/mechanisms/evm/evm_test.go b/go/mechanisms/evm/evm_test.go new file mode 100644 index 000000000..8f1b7aa82 --- /dev/null +++ b/go/mechanisms/evm/evm_test.go @@ -0,0 +1,534 @@ +package evm + +import ( + "context" + "math/big" + "strings" + "testing" + + x402 "github.com/coinbase/x402-go/v2" +) + +// Mock implementations for testing + +type mockClientSigner struct { + address string + signErr error +} + +func (m *mockClientSigner) Address() string { + return m.address +} + +func (m *mockClientSigner) SignTypedData( + domain TypedDataDomain, + types map[string][]TypedDataField, + primaryType string, + message map[string]interface{}, +) ([]byte, error) { + if m.signErr != nil { + return nil, m.signErr + } + // Return a mock signature (65 bytes) + return make([]byte, 65), nil +} + +type mockFacilitatorSigner struct { + chainID *big.Int + balances map[string]*big.Int + noncesUsed map[string]bool + verifyResult bool + txHash string + txSuccess bool +} + +func (m *mockFacilitatorSigner) ReadContract( + address string, + abi []byte, + functionName string, + args ...interface{}, +) (interface{}, error) { + if functionName == FunctionAuthorizationState { + // Check if nonce is used + nonce := args[1].([32]byte) + nonceHex := BytesToHex(nonce[:]) + return m.noncesUsed[nonceHex], nil + } + return nil, nil +} + +func (m *mockFacilitatorSigner) VerifyTypedData( + address string, + domain TypedDataDomain, + types map[string][]TypedDataField, + primaryType string, + message map[string]interface{}, + signature []byte, +) (bool, error) { + return m.verifyResult, nil +} + +func (m *mockFacilitatorSigner) WriteContract( + address string, + abi []byte, + functionName string, + args ...interface{}, +) (string, error) { + return m.txHash, nil +} + +func (m *mockFacilitatorSigner) WaitForTransactionReceipt(txHash string) (*TransactionReceipt, error) { + status := uint64(TxStatusFailed) + if m.txSuccess { + status = TxStatusSuccess + } + return &TransactionReceipt{ + Status: status, + BlockNumber: 12345, + TxHash: txHash, + }, nil +} + +func (m *mockFacilitatorSigner) GetBalance(address string, tokenAddress string) (*big.Int, error) { + key := address + ":" + tokenAddress + if balance, ok := m.balances[key]; ok { + return balance, nil + } + return big.NewInt(0), nil +} + +func (m *mockFacilitatorSigner) GetChainID() (*big.Int, error) { + if m.chainID != nil { + return m.chainID, nil + } + return ChainIDBase, nil +} + +// Tests + +func TestGetEvmChainId(t *testing.T) { + tests := []struct { + name string + network string + want *big.Int + wantErr bool + }{ + { + name: "base network", + network: "base", + want: ChainIDBase, + }, + { + name: "base-mainnet network", + network: "base-mainnet", + want: ChainIDBase, + }, + { + name: "eip155:8453 network", + network: "eip155:8453", + want: ChainIDBase, + }, + { + name: "base-sepolia network", + network: "base-sepolia", + want: ChainIDBaseSepolia, + }, + { + name: "unsupported network", + network: "unsupported", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetEvmChainId(tt.network) + if (err != nil) != tt.wantErr { + t.Errorf("GetEvmChainId() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !tt.wantErr && got.Cmp(tt.want) != 0 { + t.Errorf("GetEvmChainId() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestParseAmount(t *testing.T) { + tests := []struct { + name string + amount string + decimals int + want *big.Int + wantErr bool + }{ + { + name: "whole number", + amount: "100", + decimals: 6, + want: big.NewInt(100000000), // 100 * 10^6 + }, + { + name: "decimal amount", + amount: "1.5", + decimals: 6, + want: big.NewInt(1500000), // 1.5 * 10^6 + }, + { + name: "small decimal", + amount: "0.000001", + decimals: 6, + want: big.NewInt(1), + }, + { + name: "truncate extra decimals", + amount: "1.1234567", + decimals: 6, + want: big.NewInt(1123456), + }, + { + name: "invalid format", + amount: "1.2.3", + decimals: 6, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ParseAmount(tt.amount, tt.decimals) + if (err != nil) != tt.wantErr { + t.Errorf("ParseAmount() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !tt.wantErr && got.Cmp(tt.want) != 0 { + t.Errorf("ParseAmount() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestFormatAmount(t *testing.T) { + tests := []struct { + name string + amount *big.Int + decimals int + want string + }{ + { + name: "whole number", + amount: big.NewInt(1000000), + decimals: 6, + want: "1", + }, + { + name: "with decimals", + amount: big.NewInt(1500000), + decimals: 6, + want: "1.5", + }, + { + name: "small amount", + amount: big.NewInt(1), + decimals: 6, + want: "0.000001", + }, + { + name: "zero", + amount: big.NewInt(0), + decimals: 6, + want: "0", + }, + { + name: "nil amount", + amount: nil, + decimals: 6, + want: "0", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := FormatAmount(tt.amount, tt.decimals) + if got != tt.want { + t.Errorf("FormatAmount() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestExactEvmClient_CreatePaymentPayload(t *testing.T) { + ctx := context.Background() + signer := &mockClientSigner{ + address: "0x1234567890123456789012345678901234567890", + } + client := NewExactEvmClient(signer) + + requirements := x402.PaymentRequirements{ + Network: "base", + Asset: "USDC", + PayTo: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd", + Amount: "1500000", // 1.5 USDC in smallest unit + Extra: map[string]interface{}{ + "name": "USD Coin", + "version": "2", + }, + } + + payload, err := client.CreatePaymentPayload(ctx, 2, requirements) + if err != nil { + t.Fatalf("CreatePaymentPayload() error = %v", err) + } + + // Check basic fields + if payload.X402Version != 2 { + t.Errorf("Expected version 2, got %d", payload.X402Version) + } + if payload.Scheme != SchemeExact { + t.Errorf("Expected scheme %s, got %s", SchemeExact, payload.Scheme) + } + if payload.Network != requirements.Network { + t.Errorf("Expected network %s, got %s", requirements.Network, payload.Network) + } + + // Check payload structure + evmPayload, err := PayloadFromMap(payload.Payload) + if err != nil { + t.Fatalf("Failed to parse payload: %v", err) + } + + if evmPayload.Authorization.From != signer.address { + t.Errorf("Expected from %s, got %s", signer.address, evmPayload.Authorization.From) + } + if !strings.EqualFold(evmPayload.Authorization.To, requirements.PayTo) { + t.Errorf("Expected to %s, got %s", requirements.PayTo, evmPayload.Authorization.To) + } + if evmPayload.Authorization.Value != "1500000" { // 1.5 * 10^6 + t.Errorf("Expected value 1500000, got %s", evmPayload.Authorization.Value) + } + if evmPayload.Signature == "" { + t.Error("Expected signature to be present") + } +} + +func TestExactEvmFacilitator_Verify(t *testing.T) { + ctx := context.Background() + + signer := &mockFacilitatorSigner{ + chainID: ChainIDBase, + verifyResult: true, + balances: map[string]*big.Int{ + "0x1234567890123456789012345678901234567890:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913": big.NewInt(2000000), + }, + noncesUsed: make(map[string]bool), + } + facilitator := NewExactEvmFacilitator(signer) + + // Create a valid payload + evmPayload := &ExactEIP3009Payload{ + Signature: BytesToHex(make([]byte, 65)), + Authorization: ExactEIP3009Authorization{ + From: "0x1234567890123456789012345678901234567890", + To: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd", + Value: "1500000", + ValidAfter: "1000000", + ValidBefore: "2000000", + Nonce: BytesToHex(make([]byte, 32)), + }, + } + + payload := x402.PaymentPayload{ + X402Version: 2, + Scheme: SchemeExact, + Network: "base", + Payload: evmPayload.ToMap(), + } + + requirements := x402.PaymentRequirements{ + Network: "base", + Asset: "USDC", + PayTo: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd", + Amount: "1500000", // 1.5 USDC in smallest unit + Extra: map[string]interface{}{ + "name": "USD Coin", + "version": "2", + }, + } + + result, err := facilitator.Verify(ctx, payload, requirements) + if err != nil { + t.Fatalf("Verify() error = %v", err) + } + + if !result.IsValid { + t.Errorf("Expected valid result, got invalid: %s", result.InvalidReason) + } + if result.Payer != evmPayload.Authorization.From { + t.Errorf("Expected payer %s, got %s", evmPayload.Authorization.From, result.Payer) + } +} + +func TestExactEvmFacilitator_Settle(t *testing.T) { + ctx := context.Background() + + signer := &mockFacilitatorSigner{ + chainID: ChainIDBase, + verifyResult: true, + txHash: "0x1234567890123456789012345678901234567890123456789012345678901234", + txSuccess: true, + balances: map[string]*big.Int{ + "0x1234567890123456789012345678901234567890:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913": big.NewInt(2000000), + }, + noncesUsed: make(map[string]bool), + } + facilitator := NewExactEvmFacilitator(signer) + + // Create a valid payload + evmPayload := &ExactEIP3009Payload{ + Signature: BytesToHex(make([]byte, 65)), + Authorization: ExactEIP3009Authorization{ + From: "0x1234567890123456789012345678901234567890", + To: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd", + Value: "1500000", + ValidAfter: "1000000", + ValidBefore: "2000000", + Nonce: BytesToHex(make([]byte, 32)), + }, + } + + payload := x402.PaymentPayload{ + X402Version: 2, + Scheme: SchemeExact, + Network: "base", + Payload: evmPayload.ToMap(), + } + + requirements := x402.PaymentRequirements{ + Network: "base", + Asset: "USDC", + PayTo: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd", + Amount: "1500000", // 1.5 USDC in smallest unit + Extra: map[string]interface{}{ + "name": "USD Coin", + "version": "2", + }, + } + + result, err := facilitator.Settle(ctx, payload, requirements) + if err != nil { + t.Fatalf("Settle() error = %v", err) + } + + if !result.Success { + t.Errorf("Expected successful settlement, got failure: %s", result.ErrorReason) + } + if result.Transaction != signer.txHash { + t.Errorf("Expected tx hash %s, got %s", signer.txHash, result.Transaction) + } + if result.Payer != evmPayload.Authorization.From { + t.Errorf("Expected payer %s, got %s", evmPayload.Authorization.From, result.Payer) + } +} + +func TestExactEvmService_ParsePrice(t *testing.T) { + service := NewExactEvmService() + + tests := []struct { + name string + price string + network string + want string // expected amount + wantErr bool + }{ + { + name: "dollar format", + price: "$1.50", + network: "base", + want: "1500000", + }, + { + name: "decimal format", + price: "1.50", + network: "base", + want: "1500000", + }, + { + name: "already in smallest unit", + price: "1500000", + network: "base", + want: "1500000", + }, + { + name: "with USD suffix", + price: "1.50 USD", + network: "base", + want: "1500000", + }, + { + name: "with USDC suffix", + price: "1.50 USDC", + network: "base", + want: "1500000", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := service.ParsePrice(tt.price, x402.Network(tt.network)) + if (err != nil) != tt.wantErr { + t.Errorf("ParsePrice() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !tt.wantErr && got.Amount != tt.want { + t.Errorf("ParsePrice() amount = %v, want %v", got.Amount, tt.want) + } + }) + } +} + +func TestExactEvmService_EnhancePaymentRequirements(t *testing.T) { + ctx := context.Background() + service := NewExactEvmService() + + requirements := x402.PaymentRequirements{ + Network: "base", + PayTo: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd", + Amount: "1500000", // 1.5 USDC in smallest unit // Decimal format + } + + supportedKind := x402.SupportedKind{ + X402Version: 2, + Scheme: SchemeExact, + Network: "base", + Extra: map[string]interface{}{ + "customField": "customValue", + }, + } + + enhanced, err := service.EnhancePaymentRequirements(ctx, requirements, supportedKind, []string{"customField"}) + if err != nil { + t.Fatalf("EnhancePaymentRequirements() error = %v", err) + } + + // Check amount was converted to smallest unit + if enhanced.Amount != "1500000" { + t.Errorf("Expected amount 1500000, got %s", enhanced.Amount) + } + + // Check asset was set to default + expectedAsset := "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" // USDC on Base + if !strings.EqualFold(enhanced.Asset, expectedAsset) { + t.Errorf("Expected asset %s, got %s", expectedAsset, enhanced.Asset) + } + + // Check extra fields were added + if enhanced.Extra["name"] != "USDC" { + t.Errorf("Expected name 'USDC', got %v", enhanced.Extra["name"]) + } + if enhanced.Extra["version"] != "2" { + t.Errorf("Expected version '2', got %v", enhanced.Extra["version"]) + } + if enhanced.Extra["customField"] != "customValue" { + t.Errorf("Expected customField 'customValue', got %v", enhanced.Extra["customField"]) + } +} diff --git a/go/mechanisms/evm/example/main.go b/go/mechanisms/evm/example/main.go new file mode 100644 index 000000000..541126306 --- /dev/null +++ b/go/mechanisms/evm/example/main.go @@ -0,0 +1,124 @@ +package main + +import ( + "context" + "fmt" + "log" + + x402 "github.com/coinbase/x402-go/v2" + "github.com/coinbase/x402-go/v2/mechanisms/evm" + evmv1 "github.com/coinbase/x402-go/v2/mechanisms/evm/v1" +) + +// Example showing how to use both V1 and V2 EVM implementations +func main() { + // Example payment requirements + requirements := x402.PaymentRequirements{ + Scheme: "exact", + Network: "base", + Asset: "USDC", + Amount: "1000000", // 1 USDC in smallest unit + PayTo: "0x9876543210987654321098765432109876543210", + Extra: map[string]interface{}{ + "name": "USD Coin", + "version": "2", + }, + } + + // Using V2 (default, recommended) + fmt.Println("=== V2 Implementation ===") + clientV2 := x402.Newx402Client() + // Register V2 EVM client (supports x402 version 2) + evm.RegisterClient(&clientV2, nil, "base") // nil signer for example + + // Check if client can pay + canPayV2 := clientV2.CanPay(requirements.Network, requirements.Scheme) + fmt.Printf("V2 Client can pay: %v\n", canPayV2) + + // Using V1 (legacy support) + fmt.Println("\n=== V1 Implementation ===") + clientV1 := x402.Newx402Client() + // Register V1 EVM client (supports x402 version 1 only) + evmv1.RegisterClient(&clientV1, nil) // nil signer for example + + // Check if client can pay + canPayV1 := clientV1.CanPay(requirements.Network, requirements.Scheme) + fmt.Printf("V1 Client can pay: %v\n", canPayV1) + + // Service example + fmt.Println("\n=== Service Example ===") + + // V2 Service + serviceV2 := x402.Newx402ResourceService( + evm.RegisterService("base")..., // V2 service options + ) + + // V1 Service + serviceV1 := x402.Newx402ResourceService( + evmv1.RegisterService(), // V1 service option + ) + + // Parse price example + evmServiceV2 := evm.NewExactEvmService() + evmServiceV1 := evmv1.NewExactEvmServiceV1() + + price := "5.00" // $5.00 + network := x402.Network("base") + + assetAmountV2, err := evmServiceV2.ParsePrice(price, network) + if err != nil { + log.Printf("V2 ParsePrice error: %v", err) + } else { + fmt.Printf("V2 Parsed price: %s %s\n", assetAmountV2.Amount, assetAmountV2.Asset) + } + + assetAmountV1, err := evmServiceV1.ParsePrice(price, network) + if err != nil { + log.Printf("V1 ParsePrice error: %v", err) + } else { + fmt.Printf("V1 Parsed price: %s %s\n", assetAmountV1.Amount, assetAmountV1.Asset) + } + + // Version-specific behavior + fmt.Println("\n=== Version Differences ===") + fmt.Println("V2 Features:") + fmt.Println("- Supports x402 protocol version 2") + fmt.Println("- No buffer on validAfter (immediate use)") + fmt.Println("- Default 1 hour validity window") + fmt.Println("- Enhanced price parsing") + + fmt.Println("\nV1 Features:") + fmt.Println("- Supports x402 protocol version 1 only") + fmt.Println("- 10-minute buffer on validAfter") + fmt.Println("- Default 10-minute validity window") + fmt.Println("- Simpler price parsing") + + // Demonstrate version checking + ctx := context.Background() + supportedKindV2 := x402.SupportedKind{ + X402Version: 2, + Scheme: "exact", + Network: "base", + } + + supportedKindV1 := x402.SupportedKind{ + X402Version: 1, + Scheme: "exact", + Network: "base", + } + + // V2 service only accepts version 2 + _, errV2with1 := evmServiceV2.EnhancePaymentRequirements(ctx, requirements, supportedKindV1, nil) + if errV2with1 != nil { + fmt.Printf("\nV2 Service with version 1: %v\n", errV2with1) + } + + // V1 service only accepts version 1 + _, errV1with2 := evmServiceV1.EnhancePaymentRequirements(ctx, requirements, supportedKindV2, nil) + if errV1with2 != nil { + fmt.Printf("V1 Service with version 2: %v\n", errV1with2) + } + + _ = serviceV2 + _ = serviceV1 +} diff --git a/go/mechanisms/evm/facilitator.go b/go/mechanisms/evm/facilitator.go new file mode 100644 index 000000000..66b1ba2ac --- /dev/null +++ b/go/mechanisms/evm/facilitator.go @@ -0,0 +1,388 @@ +package evm + +import ( + "context" + "fmt" + "math/big" + "strings" + + x402 "github.com/coinbase/x402-go/v2" +) + +// ExactEvmFacilitator implements the SchemeNetworkFacilitator interface for EVM exact payments (V2) +type ExactEvmFacilitator struct { + signer FacilitatorEvmSigner +} + +// NewExactEvmFacilitator creates a new ExactEvmFacilitator +func NewExactEvmFacilitator(signer FacilitatorEvmSigner) *ExactEvmFacilitator { + return &ExactEvmFacilitator{ + signer: signer, + } +} + +// Scheme returns the scheme identifier +func (f *ExactEvmFacilitator) Scheme() string { + return SchemeExact +} + +// Verify verifies a payment payload against requirements (V2) +func (f *ExactEvmFacilitator) Verify( + ctx context.Context, + payload x402.PaymentPayload, + requirements x402.PaymentRequirements, +) (x402.VerifyResponse, error) { + // V2 specific: only handle version 2 + if payload.X402Version != 2 { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "v2 only supports x402 version 2", + }, nil + } + + // Validate scheme + if payload.Scheme != SchemeExact { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "invalid scheme", + }, nil + } + + // Validate network + if payload.Network != requirements.Network { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "network mismatch", + }, nil + } + + // Parse EVM payload + evmPayload, err := PayloadFromMap(payload.Payload) + if err != nil { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: fmt.Sprintf("invalid payload: %v", err), + }, nil + } + + // Validate signature exists + if evmPayload.Signature == "" { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "missing signature", + }, nil + } + + // Get network configuration + networkStr := string(requirements.Network) + config, err := GetNetworkConfig(networkStr) + if err != nil { + return x402.VerifyResponse{}, err + } + + // Get asset info + assetInfo, err := GetAssetInfo(networkStr, requirements.Asset) + if err != nil { + return x402.VerifyResponse{}, err + } + + // Validate authorization matches requirements + if !strings.EqualFold(evmPayload.Authorization.To, requirements.PayTo) { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "recipient mismatch", + }, nil + } + + // Parse and validate amount + authValue, ok := new(big.Int).SetString(evmPayload.Authorization.Value, 10) + if !ok { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "invalid authorization value", + }, nil + } + + // Requirements.Amount is already in the smallest unit + requiredValue, ok := new(big.Int).SetString(requirements.Amount, 10) + if !ok { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: fmt.Sprintf("invalid required amount: %s", requirements.Amount), + }, nil + } + + if authValue.Cmp(requiredValue) < 0 { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "insufficient amount", + }, nil + } + + // Check if nonce has been used + nonceUsed, err := f.checkNonceUsed(ctx, evmPayload.Authorization.From, evmPayload.Authorization.Nonce, assetInfo.Address) + if err != nil { + return x402.VerifyResponse{}, fmt.Errorf("failed to check nonce: %w", err) + } + if nonceUsed { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "nonce already used", + }, nil + } + + // Check balance + balance, err := f.signer.GetBalance(evmPayload.Authorization.From, assetInfo.Address) + if err != nil { + return x402.VerifyResponse{}, fmt.Errorf("failed to get balance: %w", err) + } + if balance.Cmp(authValue) < 0 { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "insufficient balance", + }, nil + } + + // Extract token info from requirements + tokenName := assetInfo.Name + tokenVersion := assetInfo.Version + if requirements.Extra != nil { + if name, ok := requirements.Extra["name"].(string); ok { + tokenName = name + } + if version, ok := requirements.Extra["version"].(string); ok { + tokenVersion = version + } + } + + // Verify signature + signatureBytes, err := HexToBytes(evmPayload.Signature) + if err != nil { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "invalid signature format", + }, nil + } + + valid, err := f.verifySignature( + ctx, + evmPayload.Authorization, + signatureBytes, + config.ChainID, + assetInfo.Address, + tokenName, + tokenVersion, + ) + if err != nil { + return x402.VerifyResponse{}, fmt.Errorf("failed to verify signature: %w", err) + } + + if !valid { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "invalid signature", + }, nil + } + + return x402.VerifyResponse{ + IsValid: true, + Payer: evmPayload.Authorization.From, + }, nil +} + +// Settle settles a payment on-chain (V2) +func (f *ExactEvmFacilitator) Settle( + ctx context.Context, + payload x402.PaymentPayload, + requirements x402.PaymentRequirements, +) (x402.SettleResponse, error) { + // First verify the payment + verifyResp, err := f.Verify(ctx, payload, requirements) + if err != nil { + return x402.SettleResponse{}, err + } + if !verifyResp.IsValid { + return x402.SettleResponse{ + Success: false, + ErrorReason: verifyResp.InvalidReason, + Network: payload.Network, + }, nil + } + + // Parse EVM payload + evmPayload, err := PayloadFromMap(payload.Payload) + if err != nil { + return x402.SettleResponse{ + Success: false, + ErrorReason: fmt.Sprintf("invalid payload: %v", err), + }, nil + } + + // Get asset info + networkStr := string(requirements.Network) + assetInfo, err := GetAssetInfo(networkStr, requirements.Asset) + if err != nil { + return x402.SettleResponse{}, err + } + + // Parse signature components (v, r, s) + signatureBytes, err := HexToBytes(evmPayload.Signature) + if err != nil { + return x402.SettleResponse{ + Success: false, + ErrorReason: "invalid signature format", + }, nil + } + + if len(signatureBytes) != 65 { + return x402.SettleResponse{ + Success: false, + ErrorReason: "invalid signature length", + }, nil + } + + r := signatureBytes[0:32] + s := signatureBytes[32:64] + v := signatureBytes[64] + + // Parse values + value, _ := new(big.Int).SetString(evmPayload.Authorization.Value, 10) + validAfter, _ := new(big.Int).SetString(evmPayload.Authorization.ValidAfter, 10) + validBefore, _ := new(big.Int).SetString(evmPayload.Authorization.ValidBefore, 10) + nonceBytes, _ := HexToBytes(evmPayload.Authorization.Nonce) + + // Execute transferWithAuthorization + txHash, err := f.signer.WriteContract( + assetInfo.Address, + TransferWithAuthorizationABI, + FunctionTransferWithAuthorization, + evmPayload.Authorization.From, + evmPayload.Authorization.To, + value, + validAfter, + validBefore, + [32]byte(nonceBytes), + v, + [32]byte(r), + [32]byte(s), + ) + if err != nil { + return x402.SettleResponse{ + Success: false, + ErrorReason: fmt.Sprintf("failed to execute transfer: %v", err), + }, nil + } + + // Wait for transaction confirmation + receipt, err := f.signer.WaitForTransactionReceipt(txHash) + if err != nil { + return x402.SettleResponse{ + Success: false, + ErrorReason: fmt.Sprintf("failed to get receipt: %v", err), + }, nil + } + + if receipt.Status != TxStatusSuccess { + return x402.SettleResponse{ + Success: false, + ErrorReason: "transaction failed", + Transaction: txHash, + }, nil + } + + return x402.SettleResponse{ + Success: true, + Transaction: txHash, + Network: payload.Network, + Payer: evmPayload.Authorization.From, + }, nil +} + +// checkNonceUsed checks if a nonce has already been used +func (f *ExactEvmFacilitator) checkNonceUsed(ctx context.Context, from string, nonce string, tokenAddress string) (bool, error) { + nonceBytes, err := HexToBytes(nonce) + if err != nil { + return false, err + } + + result, err := f.signer.ReadContract( + tokenAddress, + TransferWithAuthorizationABI, + FunctionAuthorizationState, + from, + [32]byte(nonceBytes), + ) + if err != nil { + return false, err + } + + used, ok := result.(bool) + if !ok { + return false, fmt.Errorf("unexpected result type from authorizationState") + } + + return used, nil +} + +// verifySignature verifies the EIP-712 signature +func (f *ExactEvmFacilitator) verifySignature( + ctx context.Context, + authorization ExactEIP3009Authorization, + signature []byte, + chainID *big.Int, + verifyingContract string, + tokenName string, + tokenVersion string, +) (bool, error) { + // Create EIP-712 domain + domain := TypedDataDomain{ + Name: tokenName, + Version: tokenVersion, + ChainID: chainID, + VerifyingContract: verifyingContract, + } + + // Define EIP-712 types + types := map[string][]TypedDataField{ + "EIP712Domain": { + {Name: "name", Type: "string"}, + {Name: "version", Type: "string"}, + {Name: "chainId", Type: "uint256"}, + {Name: "verifyingContract", Type: "address"}, + }, + "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"}, + }, + } + + // Parse values for message + value, _ := new(big.Int).SetString(authorization.Value, 10) + validAfter, _ := new(big.Int).SetString(authorization.ValidAfter, 10) + validBefore, _ := new(big.Int).SetString(authorization.ValidBefore, 10) + nonceBytes, _ := HexToBytes(authorization.Nonce) + + // Create message + message := map[string]interface{}{ + "from": authorization.From, + "to": authorization.To, + "value": value, + "validAfter": validAfter, + "validBefore": validBefore, + "nonce": nonceBytes, + } + + // Verify the signature + return f.signer.VerifyTypedData( + authorization.From, + domain, + types, + "TransferWithAuthorization", + message, + signature, + ) +} diff --git a/go/mechanisms/evm/service.go b/go/mechanisms/evm/service.go new file mode 100644 index 000000000..8348c3e56 --- /dev/null +++ b/go/mechanisms/evm/service.go @@ -0,0 +1,273 @@ +package evm + +import ( + "context" + "fmt" + "math/big" + "strings" + + x402 "github.com/coinbase/x402-go/v2" +) + +// ExactEvmService implements the SchemeNetworkService interface for EVM exact payments (V2) +type ExactEvmService struct{} + +// NewExactEvmService creates a new ExactEvmService +func NewExactEvmService() *ExactEvmService { + return &ExactEvmService{} +} + +// Scheme returns the scheme identifier +func (s *ExactEvmService) Scheme() string { + return SchemeExact +} + +// ParsePrice parses a price string and converts it to an asset amount (V2) +func (s *ExactEvmService) ParsePrice(price x402.Price, network x402.Network) (x402.AssetAmount, error) { + // Convert price to string (Price is interface{}) + priceStr, ok := price.(string) + if !ok { + priceStr = fmt.Sprintf("%v", price) + } + networkStr := string(network) + + // Handle different price formats + // Format 1: "$1.00" or "1.00 USD" + // Format 2: "1000000" (already in smallest unit) + // Format 3: "1.00" (decimal amount) + + // Remove common currency symbols and spaces + priceStr = strings.TrimSpace(priceStr) + priceStr = strings.TrimPrefix(priceStr, "$") + priceStr = strings.TrimSuffix(priceStr, " USD") + priceStr = strings.TrimSuffix(priceStr, " USDC") + priceStr = strings.TrimSpace(priceStr) + + // Get network config to determine the asset + config, err := GetNetworkConfig(networkStr) + if err != nil { + return x402.AssetAmount{}, err + } + + // Try to parse as decimal first + if strings.Contains(priceStr, ".") { + // It's a decimal amount, convert to smallest unit + amount, err := ParseAmount(priceStr, config.DefaultAsset.Decimals) + if err != nil { + return x402.AssetAmount{}, fmt.Errorf("failed to parse decimal price: %w", err) + } + + return x402.AssetAmount{ + Asset: config.DefaultAsset.Address, + Amount: amount.String(), + }, nil + } + + // Try to parse as integer (already in smallest unit) + amount, ok := new(big.Int).SetString(priceStr, 10) + if !ok { + return x402.AssetAmount{}, fmt.Errorf("invalid price format: %s", price) + } + + // Check if this looks like a reasonable amount in smallest unit + // (e.g., 1000000 for $1.00 USDC with 6 decimals) + oneUnit := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(config.DefaultAsset.Decimals)), nil) + if amount.Cmp(oneUnit) >= 0 { + // Likely already in smallest unit + return x402.AssetAmount{ + Asset: config.DefaultAsset.Address, + Amount: amount.String(), + }, nil + } + + // Small integer, treat as dollar amount + amount.Mul(amount, oneUnit) + + return x402.AssetAmount{ + Asset: config.DefaultAsset.Address, + Amount: amount.String(), + }, nil +} + +// EnhancePaymentRequirements adds scheme-specific enhancements to payment requirements (V2) +func (s *ExactEvmService) EnhancePaymentRequirements( + ctx context.Context, + requirements x402.PaymentRequirements, + supportedKind x402.SupportedKind, + extensionKeys []string, +) (x402.PaymentRequirements, error) { + // V2 specific: only handle version 2 + if supportedKind.X402Version != 2 { + return requirements, fmt.Errorf("v2 only supports x402 version 2") + } + + // Get network config + networkStr := string(requirements.Network) + config, err := GetNetworkConfig(networkStr) + if err != nil { + return requirements, err + } + + // Get asset info + var assetInfo *AssetInfo + if requirements.Asset != "" { + assetInfo, err = GetAssetInfo(networkStr, requirements.Asset) + if err != nil { + return requirements, err + } + } else { + // Use default asset if not specified + assetInfo = &config.DefaultAsset + requirements.Asset = assetInfo.Address + } + + // Ensure amount is in the correct format (smallest unit) + if requirements.Amount != "" && strings.Contains(requirements.Amount, ".") { + // Convert decimal to smallest unit + amount, err := ParseAmount(requirements.Amount, assetInfo.Decimals) + if err != nil { + return requirements, fmt.Errorf("failed to parse amount: %w", err) + } + requirements.Amount = amount.String() + } + + // Add EIP-3009 specific fields to Extra if not present + if requirements.Extra == nil { + requirements.Extra = make(map[string]interface{}) + } + + // Add token name and version for EIP-712 signing + // ONLY add if not already present (client may have specified exact values) + if _, ok := requirements.Extra["name"]; !ok { + requirements.Extra["name"] = assetInfo.Name + } + if _, ok := requirements.Extra["version"]; !ok { + requirements.Extra["version"] = assetInfo.Version + } + + // Copy extensions from supportedKind if provided + if supportedKind.Extra != nil { + for _, key := range extensionKeys { + if val, ok := supportedKind.Extra[key]; ok { + requirements.Extra[key] = val + } + } + } + + return requirements, nil +} + +// GetDisplayAmount formats an amount for display +func (s *ExactEvmService) GetDisplayAmount(amount string, network string, asset string) (string, error) { + // Get asset info + assetInfo, err := GetAssetInfo(network, asset) + if err != nil { + return "", err + } + + // Parse amount + amountBig, ok := new(big.Int).SetString(amount, 10) + if !ok { + return "", fmt.Errorf("invalid amount: %s", amount) + } + + // Format with decimals + formatted := FormatAmount(amountBig, assetInfo.Decimals) + + // Add currency symbol + return "$" + formatted + " USDC", nil +} + +// ValidatePaymentRequirements validates that requirements are valid for this scheme +func (s *ExactEvmService) ValidatePaymentRequirements(requirements x402.PaymentRequirements) error { + // Check network is supported + networkStr := string(requirements.Network) + if !IsValidNetwork(networkStr) { + return fmt.Errorf("unsupported network: %s", requirements.Network) + } + + // Check PayTo is a valid address + if !IsValidAddress(requirements.PayTo) { + return fmt.Errorf("invalid PayTo address: %s", requirements.PayTo) + } + + // Check amount is valid + if requirements.Amount == "" { + return fmt.Errorf("amount is required") + } + + amount, ok := new(big.Int).SetString(requirements.Amount, 10) + if !ok || amount.Sign() <= 0 { + return fmt.Errorf("invalid amount: %s", requirements.Amount) + } + + // Check asset is valid if specified + if requirements.Asset != "" && !IsValidAddress(requirements.Asset) { + // Try to look it up as a symbol + _, err := GetAssetInfo(networkStr, requirements.Asset) + if err != nil { + return fmt.Errorf("invalid asset: %s", requirements.Asset) + } + } + + return nil +} + +// ConvertToTokenAmount converts a decimal amount to token smallest unit +func (s *ExactEvmService) ConvertToTokenAmount(decimalAmount string, network string) (string, error) { + config, err := GetNetworkConfig(network) + if err != nil { + return "", err + } + + amount, err := ParseAmount(decimalAmount, config.DefaultAsset.Decimals) + if err != nil { + return "", err + } + + return amount.String(), nil +} + +// ConvertFromTokenAmount converts from token smallest unit to decimal +func (s *ExactEvmService) ConvertFromTokenAmount(tokenAmount string, network string) (string, error) { + config, err := GetNetworkConfig(network) + if err != nil { + return "", err + } + + amount, ok := new(big.Int).SetString(tokenAmount, 10) + if !ok { + return "", fmt.Errorf("invalid token amount: %s", tokenAmount) + } + + return FormatAmount(amount, config.DefaultAsset.Decimals), nil +} + +// GetSupportedNetworks returns the list of supported networks +func (s *ExactEvmService) GetSupportedNetworks() []string { + networks := make([]string, 0, len(NetworkConfigs)) + for network := range NetworkConfigs { + networks = append(networks, network) + } + return networks +} + +// GetSupportedAssets returns the list of supported assets for a network +func (s *ExactEvmService) GetSupportedAssets(network string) ([]string, error) { + config, err := GetNetworkConfig(network) + if err != nil { + return nil, err + } + + assets := make([]string, 0, len(config.SupportedAssets)) + for symbol := range config.SupportedAssets { + assets = append(assets, symbol) + } + + // Also add the addresses + for _, asset := range config.SupportedAssets { + assets = append(assets, asset.Address) + } + + return assets, nil +} diff --git a/go/mechanisms/evm/types.go b/go/mechanisms/evm/types.go new file mode 100644 index 000000000..1b7e02a1a --- /dev/null +++ b/go/mechanisms/evm/types.go @@ -0,0 +1,153 @@ +package evm + +import ( + "math/big" +) + +// ExactEIP3009Authorization represents the EIP-3009 TransferWithAuthorization data +type ExactEIP3009Authorization struct { + From string `json:"from"` // Ethereum address (hex) + To string `json:"to"` // Ethereum address (hex) + Value string `json:"value"` // Amount in wei as string + ValidAfter string `json:"validAfter"` // Unix timestamp as string + ValidBefore string `json:"validBefore"` // Unix timestamp as string + Nonce string `json:"nonce"` // 32-byte nonce as hex string +} + +// ExactEIP3009Payload represents the exact payment payload for EVM networks +type ExactEIP3009Payload struct { + Signature string `json:"signature,omitempty"` + Authorization ExactEIP3009Authorization `json:"authorization"` +} + +// ExactEvmPayloadV1 is an alias for ExactEIP3009Payload (v1 compatibility) +type ExactEvmPayloadV1 = ExactEIP3009Payload + +// ExactEvmPayloadV2 is an alias for ExactEIP3009Payload (v2 compatibility) +type ExactEvmPayloadV2 = ExactEIP3009Payload + +// ClientEvmSigner defines the interface for client-side EVM signing operations +type ClientEvmSigner interface { + // Address returns the signer's Ethereum address + Address() string + + // SignTypedData signs EIP-712 typed data + SignTypedData(domain TypedDataDomain, types map[string][]TypedDataField, primaryType string, message map[string]interface{}) ([]byte, error) +} + +// FacilitatorEvmSigner defines the interface for facilitator EVM operations +type FacilitatorEvmSigner interface { + // ReadContract reads data from a smart contract + ReadContract(address string, abi []byte, functionName string, args ...interface{}) (interface{}, error) + + // VerifyTypedData verifies an EIP-712 signature + VerifyTypedData(address string, domain TypedDataDomain, types map[string][]TypedDataField, primaryType string, message map[string]interface{}, signature []byte) (bool, error) + + // WriteContract executes a smart contract transaction + WriteContract(address string, abi []byte, functionName string, args ...interface{}) (string, error) + + // WaitForTransactionReceipt waits for a transaction to be mined + WaitForTransactionReceipt(txHash string) (*TransactionReceipt, error) + + // GetBalance gets the balance of an address for a specific token + GetBalance(address string, tokenAddress string) (*big.Int, error) + + // GetChainID returns the chain ID of the connected network + GetChainID() (*big.Int, error) +} + +// TypedDataDomain represents the EIP-712 domain separator +type TypedDataDomain struct { + Name string `json:"name"` + Version string `json:"version"` + ChainID *big.Int `json:"chainId"` + VerifyingContract string `json:"verifyingContract"` +} + +// TypedDataField represents a field in EIP-712 typed data +type TypedDataField struct { + Name string `json:"name"` + Type string `json:"type"` +} + +// TransactionReceipt represents the receipt of a mined transaction +type TransactionReceipt struct { + Status uint64 `json:"status"` + BlockNumber uint64 `json:"blockNumber"` + TxHash string `json:"transactionHash"` +} + +// AssetInfo contains information about an ERC20 token +type AssetInfo struct { + Address string + Name string + Version string + Decimals int +} + +// NetworkConfig contains network-specific configuration +type NetworkConfig struct { + ChainID *big.Int + DefaultAsset AssetInfo + SupportedAssets map[string]AssetInfo // symbol -> AssetInfo +} + +// PayloadToMap converts an ExactEIP3009Payload to a map for JSON marshaling +func (p *ExactEIP3009Payload) ToMap() map[string]interface{} { + result := map[string]interface{}{ + "authorization": map[string]interface{}{ + "from": p.Authorization.From, + "to": p.Authorization.To, + "value": p.Authorization.Value, + "validAfter": p.Authorization.ValidAfter, + "validBefore": p.Authorization.ValidBefore, + "nonce": p.Authorization.Nonce, + }, + } + if p.Signature != "" { + result["signature"] = p.Signature + } + return result +} + +// PayloadFromMap creates an ExactEIP3009Payload from a map +func PayloadFromMap(data map[string]interface{}) (*ExactEIP3009Payload, error) { + payload := &ExactEIP3009Payload{} + + if sig, ok := data["signature"].(string); ok { + payload.Signature = sig + } + + if auth, ok := data["authorization"].(map[string]interface{}); ok { + if from, ok := auth["from"].(string); ok { + payload.Authorization.From = from + } + if to, ok := auth["to"].(string); ok { + payload.Authorization.To = to + } + if value, ok := auth["value"].(string); ok { + payload.Authorization.Value = value + } + if validAfter, ok := auth["validAfter"].(string); ok { + payload.Authorization.ValidAfter = validAfter + } + if validBefore, ok := auth["validBefore"].(string); ok { + payload.Authorization.ValidBefore = validBefore + } + if nonce, ok := auth["nonce"].(string); ok { + payload.Authorization.Nonce = nonce + } + } + + return payload, nil +} + +// IsValidNetwork checks if the network is supported for EVM +func IsValidNetwork(network string) bool { + switch network { + case "eip155:1", "eip155:8453", "eip155:84532", "base", "base-sepolia", "base-mainnet": + return true + default: + return false + } +} diff --git a/go/mechanisms/evm/utils.go b/go/mechanisms/evm/utils.go new file mode 100644 index 000000000..a17fd8b84 --- /dev/null +++ b/go/mechanisms/evm/utils.go @@ -0,0 +1,208 @@ +package evm + +import ( + "crypto/rand" + "encoding/hex" + "fmt" + "math/big" + "strings" + "time" +) + +// GetEvmChainId returns the chain ID for a given network +func GetEvmChainId(network string) (*big.Int, error) { + networkStr := network + + // Normalize network name + switch networkStr { + case "base", "base-mainnet": + networkStr = "eip155:8453" + case "base-sepolia": + networkStr = "eip155:84532" + } + + if config, ok := NetworkConfigs[networkStr]; ok { + return config.ChainID, nil + } + + // Try to parse from CAIP-2 format (eip155:chainId) + if strings.HasPrefix(networkStr, "eip155:") { + chainIdStr := strings.TrimPrefix(networkStr, "eip155:") + chainId, ok := new(big.Int).SetString(chainIdStr, 10) + if ok { + return chainId, nil + } + } + + return nil, fmt.Errorf("unsupported network: %s", network) +} + +// CreateNonce generates a random 32-byte nonce +func CreateNonce() (string, error) { + nonce := make([]byte, 32) + _, err := rand.Read(nonce) + if err != nil { + return "", fmt.Errorf("failed to generate nonce: %w", err) + } + return "0x" + hex.EncodeToString(nonce), nil +} + +// NormalizeAddress ensures an Ethereum address is in the correct format +func NormalizeAddress(address string) string { + // Remove 0x prefix if present + addr := strings.TrimPrefix(strings.ToLower(address), "0x") + + // Add 0x prefix back + return "0x" + addr +} + +// IsValidAddress checks if a string is a valid Ethereum address +func IsValidAddress(address string) bool { + // Remove 0x prefix if present + addr := strings.TrimPrefix(address, "0x") + + // Check length (40 hex characters) + if len(addr) != 40 { + return false + } + + // Check if all characters are valid hex + _, err := hex.DecodeString(addr) + return err == nil +} + +// ParseAmount converts a decimal string amount to wei based on token decimals +func ParseAmount(amount string, decimals int) (*big.Int, error) { + // Parse the decimal amount + parts := strings.Split(amount, ".") + if len(parts) > 2 { + return nil, fmt.Errorf("invalid amount format: %s", amount) + } + + // Parse integer part + intPart, ok := new(big.Int).SetString(parts[0], 10) + if !ok { + return nil, fmt.Errorf("invalid integer part: %s", parts[0]) + } + + // Handle decimal part + decPart := new(big.Int) + if len(parts) == 2 && parts[1] != "" { + // Pad or truncate decimal part to match token decimals + decStr := parts[1] + if len(decStr) > decimals { + decStr = decStr[:decimals] + } else { + decStr = decStr + strings.Repeat("0", decimals-len(decStr)) + } + + decPart, ok = new(big.Int).SetString(decStr, 10) + if !ok { + return nil, fmt.Errorf("invalid decimal part: %s", parts[1]) + } + } + + // Calculate total in smallest unit + multiplier := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(decimals)), nil) + result := new(big.Int).Mul(intPart, multiplier) + result.Add(result, decPart) + + return result, nil +} + +// FormatAmount converts an amount in wei to a decimal string +func FormatAmount(amount *big.Int, decimals int) string { + if amount == nil { + return "0" + } + + divisor := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(decimals)), nil) + quotient, remainder := new(big.Int).DivMod(amount, divisor, new(big.Int)) + + // Format the decimal part with leading zeros + decStr := remainder.String() + if len(decStr) < decimals { + decStr = strings.Repeat("0", decimals-len(decStr)) + decStr + } + + // Remove trailing zeros + decStr = strings.TrimRight(decStr, "0") + + if decStr == "" { + return quotient.String() + } + + return quotient.String() + "." + decStr +} + +// GetNetworkConfig returns the configuration for a network +func GetNetworkConfig(network string) (*NetworkConfig, error) { + networkStr := network + + // Normalize network name + switch networkStr { + case "base", "base-mainnet": + networkStr = "eip155:8453" + case "base-sepolia": + networkStr = "eip155:84532" + } + + if config, ok := NetworkConfigs[networkStr]; ok { + return &config, nil + } + + return nil, fmt.Errorf("unsupported network: %s", network) +} + +// GetAssetInfo returns information about an asset on a network +func GetAssetInfo(network string, assetSymbolOrAddress string) (*AssetInfo, error) { + config, err := GetNetworkConfig(network) + if err != nil { + return nil, err + } + + // Check if it's an address + if IsValidAddress(assetSymbolOrAddress) { + // For now, assume it's USDC if the address matches + normalizedAddr := NormalizeAddress(assetSymbolOrAddress) + if normalizedAddr == NormalizeAddress(config.DefaultAsset.Address) { + return &config.DefaultAsset, nil + } + // Could extend this to support more tokens + return &AssetInfo{ + Address: normalizedAddr, + Name: "Unknown Token", + Version: "1", + Decimals: 18, // Default to 18 decimals for unknown tokens + }, nil + } + + // Look up by symbol + if asset, ok := config.SupportedAssets[strings.ToUpper(assetSymbolOrAddress)]; ok { + return &asset, nil + } + + // Default to the network's default asset + return &config.DefaultAsset, nil +} + +// CreateValidityWindow creates valid after/before timestamps +func CreateValidityWindow(duration time.Duration) (validAfter, validBefore *big.Int) { + now := time.Now().Unix() + // Add 30 second buffer to account for clock skew and block time + validAfter = big.NewInt(now - 30) + validBefore = big.NewInt(now + int64(duration.Seconds())) + return validAfter, validBefore +} + +// HexToBytes converts a hex string to bytes +func HexToBytes(hexStr string) ([]byte, error) { + // Remove 0x prefix if present + cleaned := strings.TrimPrefix(hexStr, "0x") + return hex.DecodeString(cleaned) +} + +// BytesToHex converts bytes to a hex string with 0x prefix +func BytesToHex(data []byte) string { + return "0x" + hex.EncodeToString(data) +} diff --git a/go/mechanisms/evm/v1/README.md b/go/mechanisms/evm/v1/README.md new file mode 100644 index 000000000..22a4381f8 --- /dev/null +++ b/go/mechanisms/evm/v1/README.md @@ -0,0 +1,48 @@ +# EVM V1 Implementation + +This package contains the V1 implementation of the EVM mechanism for x402. + +## Key Differences from V2 + +1. **Version Support**: Only supports x402 version 1 (v2 supports version 2) + +2. **ValidAfter Buffer**: V1 subtracts 10 minutes from the current time for `validAfter` to ensure the transaction is immediately valid. V2 uses the current time directly. + +3. **Default Validity Window**: V1 uses a 10-minute window by default, V2 uses 1 hour. + +4. **Price Parsing**: V1 has simpler price parsing logic, defaulting to USDC for the network. + +## Usage + +```go +import ( + x402 "github.com/coinbase/x402-go/v2" + evmv1 "github.com/coinbase/x402-go/v2/mechanisms/evm/v1" +) + +// Register V1 client +client := x402.Newx402Client() +client = evmv1.RegisterClient(client, signer) + +// Register V1 facilitator +facilitator := x402.Newx402Facilitator() +facilitator = evmv1.RegisterFacilitator(facilitator, signer) + +// Register V1 service +service := x402.Newx402ResourceService( + evmv1.RegisterService(), +) +``` + +## Migration to V2 + +To migrate from V1 to V2: + +1. Update x402 version in payment requirements from 1 to 2 +2. Remove any custom `validAfter` buffer logic (V2 handles this) +3. Update imports from `evm/v1` to `evm` +4. Test thoroughly, especially around timing windows + +## Compatibility + +V1 is maintained for backward compatibility with existing integrations. New implementations should use V2 (the parent `evm` package). diff --git a/go/mechanisms/evm/v1/client.go b/go/mechanisms/evm/v1/client.go new file mode 100644 index 000000000..b28277b17 --- /dev/null +++ b/go/mechanisms/evm/v1/client.go @@ -0,0 +1,181 @@ +package v1 + +import ( + "context" + "fmt" + "math/big" + "time" + + x402 "github.com/coinbase/x402-go/v2" + "github.com/coinbase/x402-go/v2/mechanisms/evm" +) + +// ExactEvmClientV1 implements the SchemeNetworkClient interface for EVM exact payments (V1) +type ExactEvmClientV1 struct { + signer evm.ClientEvmSigner +} + +// NewExactEvmClientV1 creates a new ExactEvmClientV1 +func NewExactEvmClientV1(signer evm.ClientEvmSigner) *ExactEvmClientV1 { + return &ExactEvmClientV1{ + signer: signer, + } +} + +// Scheme returns the scheme identifier +func (c *ExactEvmClientV1) Scheme() string { + return evm.SchemeExact +} + +// CreatePaymentPayload creates a payment payload for the exact scheme (V1) +func (c *ExactEvmClientV1) CreatePaymentPayload( + ctx context.Context, + version int, + requirements x402.PaymentRequirements, +) (x402.PaymentPayload, error) { + // V1 only supports version 1 + if version != 1 { + return x402.PaymentPayload{}, fmt.Errorf("v1 only supports x402 version 1, got %d", version) + } + + // Validate network + networkStr := string(requirements.Network) + if !evm.IsValidNetwork(networkStr) { + return x402.PaymentPayload{}, fmt.Errorf("unsupported network: %s", requirements.Network) + } + + // Get network configuration + config, err := evm.GetNetworkConfig(networkStr) + if err != nil { + return x402.PaymentPayload{}, err + } + + // Get asset info + assetInfo, err := evm.GetAssetInfo(networkStr, requirements.Asset) + if err != nil { + return x402.PaymentPayload{}, err + } + + // V1: Use MaxAmountRequired if present, fallback to Amount + amountStr := requirements.MaxAmountRequired + if amountStr == "" { + amountStr = requirements.Amount + } + + value, ok := new(big.Int).SetString(amountStr, 10) + if !ok { + return x402.PaymentPayload{}, fmt.Errorf("invalid amount: %s", amountStr) + } + + // Create nonce + nonce, err := evm.CreateNonce() + if err != nil { + return x402.PaymentPayload{}, err + } + + // V1 specific: validAfter is 10 minutes before now, validBefore is 10 minutes from now + now := time.Now().Unix() + validAfter := big.NewInt(now - 600) // 10 minutes before + timeout := int64(600) // Default 10 minutes + if requirements.MaxTimeoutSeconds > 0 { + timeout = int64(requirements.MaxTimeoutSeconds) + } + validBefore := big.NewInt(now + timeout) + + // Extract extra fields for EIP-3009 + tokenName := assetInfo.Name + tokenVersion := assetInfo.Version + if requirements.Extra != nil { + if name, ok := requirements.Extra["name"].(string); ok { + tokenName = name + } + if version, ok := requirements.Extra["version"].(string); ok { + tokenVersion = version + } + } + + // Create authorization + authorization := evm.ExactEIP3009Authorization{ + From: c.signer.Address(), + To: requirements.PayTo, + Value: value.String(), + ValidAfter: validAfter.String(), + ValidBefore: validBefore.String(), + Nonce: nonce, + } + + // Sign the authorization + signature, err := c.signAuthorization(ctx, authorization, config.ChainID, assetInfo.Address, tokenName, tokenVersion) + if err != nil { + return x402.PaymentPayload{}, fmt.Errorf("failed to sign authorization: %w", err) + } + + // Create payload + evmPayload := &evm.ExactEIP3009Payload{ + Signature: evm.BytesToHex(signature), + Authorization: authorization, + } + + // Convert to PaymentPayload + return x402.PaymentPayload{ + X402Version: 1, + Scheme: evm.SchemeExact, + Network: requirements.Network, + Payload: evmPayload.ToMap(), + }, nil +} + +// signAuthorization signs the EIP-3009 authorization using EIP-712 +func (c *ExactEvmClientV1) signAuthorization( + ctx context.Context, + authorization evm.ExactEIP3009Authorization, + chainID *big.Int, + verifyingContract string, + tokenName string, + tokenVersion string, +) ([]byte, error) { + // Create EIP-712 domain + domain := evm.TypedDataDomain{ + Name: tokenName, + Version: tokenVersion, + ChainID: chainID, + VerifyingContract: verifyingContract, + } + + // Define EIP-712 types + types := map[string][]evm.TypedDataField{ + "EIP712Domain": { + {Name: "name", Type: "string"}, + {Name: "version", Type: "string"}, + {Name: "chainId", Type: "uint256"}, + {Name: "verifyingContract", Type: "address"}, + }, + "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"}, + }, + } + + // Parse values for message + value, _ := new(big.Int).SetString(authorization.Value, 10) + validAfter, _ := new(big.Int).SetString(authorization.ValidAfter, 10) + validBefore, _ := new(big.Int).SetString(authorization.ValidBefore, 10) + nonceBytes, _ := evm.HexToBytes(authorization.Nonce) + + // Create message + message := map[string]interface{}{ + "from": authorization.From, + "to": authorization.To, + "value": value, + "validAfter": validAfter, + "validBefore": validBefore, + "nonce": nonceBytes, + } + + // Sign the typed data + return c.signer.SignTypedData(domain, types, "TransferWithAuthorization", message) +} diff --git a/go/mechanisms/evm/v1/evm.go b/go/mechanisms/evm/v1/evm.go new file mode 100644 index 000000000..04af8dfc2 --- /dev/null +++ b/go/mechanisms/evm/v1/evm.go @@ -0,0 +1,25 @@ +// Package v1 provides the V1 implementation of the EVM mechanism for x402 +package v1 + +import ( + x402 "github.com/coinbase/x402-go/v2" + "github.com/coinbase/x402-go/v2/mechanisms/evm" +) + +// RegisterClient registers the V1 EVM client with an x402Client +func RegisterClient(client *x402.X402Client, signer evm.ClientEvmSigner) *x402.X402Client { + evmClient := NewExactEvmClientV1(signer) + return client.RegisterScheme(evm.SchemeExact, evmClient) +} + +// RegisterFacilitator registers the V1 EVM facilitator with an x402Facilitator +func RegisterFacilitator(facilitator *x402.X402Facilitator, signer evm.FacilitatorEvmSigner) *x402.X402Facilitator { + evmFacilitator := NewExactEvmFacilitatorV1(signer) + return facilitator.RegisterScheme(evm.SchemeExact, evmFacilitator) +} + +// RegisterService returns the option to register the V1 EVM service with an x402ResourceService +func RegisterService() x402.ResourceServiceOption { + evmService := NewExactEvmServiceV1() + return x402.WithSchemeService(evm.SchemeExact, evmService) +} diff --git a/go/mechanisms/evm/v1/evm_test.go b/go/mechanisms/evm/v1/evm_test.go new file mode 100644 index 000000000..4b9d80cec --- /dev/null +++ b/go/mechanisms/evm/v1/evm_test.go @@ -0,0 +1,270 @@ +package v1 + +import ( + "context" + "math/big" + "testing" + + x402 "github.com/coinbase/x402-go/v2" + "github.com/coinbase/x402-go/v2/mechanisms/evm" +) + +// Mock signer for testing +type mockClientSigner struct{} + +func (m *mockClientSigner) Address() string { + return "0x1234567890123456789012345678901234567890" +} + +func (m *mockClientSigner) SignTypedData( + domain evm.TypedDataDomain, + types map[string][]evm.TypedDataField, + primaryType string, + message map[string]interface{}, +) ([]byte, error) { + // Return a mock signature + return make([]byte, 65), nil +} + +// Mock facilitator signer for testing +type mockFacilitatorSigner struct{} + +func (m *mockFacilitatorSigner) Address() string { + return "0xfacilitator" +} + +func (m *mockFacilitatorSigner) GetBalance(address string, tokenAddress string) (*big.Int, error) { + // Return sufficient balance + return big.NewInt(1000000000), nil +} + +func (m *mockFacilitatorSigner) ReadContract( + contractAddress string, + abi []byte, + functionName string, + args ...interface{}, +) (interface{}, error) { + // Mock nonce check - return false (not used) + return false, nil +} + +func (m *mockFacilitatorSigner) WriteContract( + contractAddress string, + abi []byte, + functionName string, + args ...interface{}, +) (string, error) { + return "0xtxhash", nil +} + +func (m *mockFacilitatorSigner) WaitForTransactionReceipt(txHash string) (*evm.TransactionReceipt, error) { + return &evm.TransactionReceipt{ + Status: evm.TxStatusSuccess, + }, nil +} + +func (m *mockFacilitatorSigner) VerifyTypedData( + address string, + domain evm.TypedDataDomain, + types map[string][]evm.TypedDataField, + primaryType string, + message map[string]interface{}, + signature []byte, +) (bool, error) { + return true, nil +} + +func (m *mockFacilitatorSigner) GetChainID() (*big.Int, error) { + return big.NewInt(8453), nil // Base mainnet +} + +func TestV1ClientCreatePaymentPayload(t *testing.T) { + client := NewExactEvmClientV1(&mockClientSigner{}) + + requirements := x402.PaymentRequirements{ + Scheme: "exact", + Network: "base", + Asset: "USDC", + Amount: "1000000", + PayTo: "0x9876543210987654321098765432109876543210", + Extra: map[string]interface{}{ + "name": "USD Coin", + "version": "2", + }, + } + + payload, err := client.CreatePaymentPayload(context.Background(), 1, requirements) + if err != nil { + t.Fatalf("Failed to create payment payload: %v", err) + } + + // V1 specific: should only accept version 1 + if payload.X402Version != 1 { + t.Errorf("Expected X402Version 1, got %d", payload.X402Version) + } + + // Try with version 2 - should fail + _, err = client.CreatePaymentPayload(context.Background(), 2, requirements) + if err == nil { + t.Error("Expected error when using version 2 with V1 client") + } + if err.Error() != "v1 only supports x402 version 1, got 2" { + t.Errorf("Unexpected error message: %v", err) + } +} + +func TestV1FacilitatorVerify(t *testing.T) { + facilitator := NewExactEvmFacilitatorV1(&mockFacilitatorSigner{}) + + requirements := x402.PaymentRequirements{ + Scheme: "exact", + Network: "base", + Asset: "USDC", + Amount: "1000000", + PayTo: "0x9876543210987654321098765432109876543210", + Extra: map[string]interface{}{ + "name": "USD Coin", + "version": "2", + }, + } + + // Create a v1 payload + payload := x402.PaymentPayload{ + X402Version: 1, + Scheme: "exact", + Network: "base", + Payload: map[string]interface{}{ + "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", // 65 bytes hex encoded + "authorization": map[string]interface{}{ + "from": "0x1234567890123456789012345678901234567890", + "to": requirements.PayTo, + "value": requirements.Amount, + "validAfter": "0", + "validBefore": "9999999999", + "nonce": "0x0000000000000000000000000000000000000000000000000000000000000000", // 32 bytes hex encoded + }, + }, + } + + resp, err := facilitator.Verify(context.Background(), payload, requirements) + if err != nil { + t.Fatalf("Failed to verify payment: %v", err) + } + + if !resp.IsValid { + t.Errorf("Expected valid payment, got invalid: %s", resp.InvalidReason) + } + + // Test with v2 payload - should fail + payload.X402Version = 2 + resp, err = facilitator.Verify(context.Background(), payload, requirements) + if err != nil { + t.Fatalf("Failed to verify payment: %v", err) + } + + if resp.IsValid { + t.Error("Expected invalid payment for v2 with V1 facilitator") + } + if resp.InvalidReason != "v1 only supports x402 version 1" { + t.Errorf("Unexpected invalid reason: %s", resp.InvalidReason) + } +} + +func TestV1ServiceParsePrice(t *testing.T) { + service := NewExactEvmServiceV1() + + tests := []struct { + name string + price x402.Price + network x402.Network + expected string + }{ + { + name: "string amount", + price: "5.00", + network: "base", + expected: "5000000", + }, + { + name: "float amount", + price: 5.0, + network: "base", + expected: "5000000", + }, + { + name: "int amount", + price: 5, + network: "base", + expected: "5000000", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assetAmount, err := service.ParsePrice(tt.price, tt.network) + if err != nil { + t.Fatalf("Failed to parse price: %v", err) + } + + if assetAmount.Amount != tt.expected { + t.Errorf("Expected amount %s, got %s", tt.expected, assetAmount.Amount) + } + }) + } +} + +func TestV1ServiceEnhancePaymentRequirements(t *testing.T) { + service := NewExactEvmServiceV1() + + requirements := x402.PaymentRequirements{ + Scheme: "exact", + Network: "base", + Asset: "USDC", + Amount: "1000000", + PayTo: "0x9876543210987654321098765432109876543210", + } + + supportedKind := x402.SupportedKind{ + X402Version: 1, + Scheme: "exact", + Network: "base", + } + + enhanced, err := service.EnhancePaymentRequirements( + context.Background(), + requirements, + supportedKind, + []string{}, + ) + if err != nil { + t.Fatalf("Failed to enhance requirements: %v", err) + } + + // Check V1 specific enhancements + if enhanced.Extra == nil { + t.Fatal("Expected extra map to be populated") + } + + // Check EIP-712 domain parameters + if enhanced.Extra["name"] == nil { + t.Error("Expected name in extra") + } + if enhanced.Extra["version"] == nil { + t.Error("Expected version in extra") + } + + // Test with v2 supportedKind - should fail + supportedKind.X402Version = 2 + _, err = service.EnhancePaymentRequirements( + context.Background(), + requirements, + supportedKind, + []string{}, + ) + if err == nil { + t.Error("Expected error when using version 2 with V1 service") + } + if err.Error() != "v1 only supports x402 version 1" { + t.Errorf("Unexpected error message: %v", err) + } +} diff --git a/go/mechanisms/evm/v1/facilitator.go b/go/mechanisms/evm/v1/facilitator.go new file mode 100644 index 000000000..222658957 --- /dev/null +++ b/go/mechanisms/evm/v1/facilitator.go @@ -0,0 +1,393 @@ +package v1 + +import ( + "context" + "fmt" + "math/big" + "strings" + "time" + + x402 "github.com/coinbase/x402-go/v2" + "github.com/coinbase/x402-go/v2/mechanisms/evm" +) + +// ExactEvmFacilitatorV1 implements the SchemeNetworkFacilitator interface for EVM exact payments (V1) +type ExactEvmFacilitatorV1 struct { + signer evm.FacilitatorEvmSigner +} + +// NewExactEvmFacilitatorV1 creates a new ExactEvmFacilitatorV1 +func NewExactEvmFacilitatorV1(signer evm.FacilitatorEvmSigner) *ExactEvmFacilitatorV1 { + return &ExactEvmFacilitatorV1{ + signer: signer, + } +} + +// Scheme returns the scheme identifier +func (f *ExactEvmFacilitatorV1) Scheme() string { + return evm.SchemeExact +} + +// Verify verifies a payment payload against requirements (V1) +func (f *ExactEvmFacilitatorV1) Verify( + ctx context.Context, + payload x402.PaymentPayload, + requirements x402.PaymentRequirements, +) (x402.VerifyResponse, error) { + // V1 specific: only handle version 1 + if payload.X402Version != 1 { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "v1 only supports x402 version 1", + }, nil + } + + // Validate scheme + if payload.Scheme != evm.SchemeExact || requirements.Scheme != evm.SchemeExact { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "unsupported_scheme", + }, nil + } + + // Validate network + if payload.Network != requirements.Network { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "network_mismatch", + }, nil + } + + // Parse EVM payload + evmPayload, err := evm.PayloadFromMap(payload.Payload) + if err != nil { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: fmt.Sprintf("invalid payload: %v", err), + }, nil + } + + // Validate signature exists + if evmPayload.Signature == "" { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "missing signature", + }, nil + } + + // Get network configuration + networkStr := string(requirements.Network) + config, err := evm.GetNetworkConfig(networkStr) + if err != nil { + return x402.VerifyResponse{}, err + } + + // Get asset info + assetInfo, err := evm.GetAssetInfo(networkStr, requirements.Asset) + if err != nil { + return x402.VerifyResponse{}, err + } + + // Check EIP-712 domain parameters + if requirements.Extra == nil || requirements.Extra["name"] == nil || requirements.Extra["version"] == nil { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "missing_eip712_domain", + Payer: evmPayload.Authorization.From, + }, nil + } + + // Validate authorization matches requirements + if !strings.EqualFold(evmPayload.Authorization.To, requirements.PayTo) { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "invalid_exact_evm_payload_recipient_mismatch", + Payer: evmPayload.Authorization.From, + }, nil + } + + // Parse and validate amount + authValue, ok := new(big.Int).SetString(evmPayload.Authorization.Value, 10) + if !ok || evmPayload.Authorization.Value == "" { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: fmt.Sprintf("invalid authorization value: %s", evmPayload.Authorization.Value), + Payer: evmPayload.Authorization.From, + }, nil + } + + // V1: Use MaxAmountRequired if present, fallback to Amount + amountStr := requirements.MaxAmountRequired + if amountStr == "" { + amountStr = requirements.Amount + } + + requiredValue, ok := new(big.Int).SetString(amountStr, 10) + if !ok { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: fmt.Sprintf("invalid required amount: %s", amountStr), + Payer: evmPayload.Authorization.From, + }, nil + } + + if authValue.Cmp(requiredValue) < 0 { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "invalid_exact_evm_payload_authorization_value", + Payer: evmPayload.Authorization.From, + }, nil + } + + // V1 specific: Check validBefore is in the future (with 6 second buffer for block time) + now := time.Now().Unix() + validBefore, _ := new(big.Int).SetString(evmPayload.Authorization.ValidBefore, 10) + if validBefore.Cmp(big.NewInt(now+6)) < 0 { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "invalid_exact_evm_payload_authorization_valid_before", + Payer: evmPayload.Authorization.From, + }, nil + } + + // V1 specific: Check validAfter is not in the future + validAfter, _ := new(big.Int).SetString(evmPayload.Authorization.ValidAfter, 10) + if validAfter.Cmp(big.NewInt(now)) > 0 { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "invalid_exact_evm_payload_authorization_valid_after", + Payer: evmPayload.Authorization.From, + }, nil + } + + // Check balance + balance, err := f.signer.GetBalance(evmPayload.Authorization.From, assetInfo.Address) + if err == nil && balance.Cmp(requiredValue) < 0 { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "insufficient_funds", + Payer: evmPayload.Authorization.From, + }, nil + } + + // Extract token info from requirements + tokenName := requirements.Extra["name"].(string) + tokenVersion := requirements.Extra["version"].(string) + + // Verify signature + signatureBytes, err := evm.HexToBytes(evmPayload.Signature) + if err != nil { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "invalid signature format", + Payer: evmPayload.Authorization.From, + }, nil + } + + valid, err := f.verifySignature( + ctx, + evmPayload.Authorization, + signatureBytes, + config.ChainID, + assetInfo.Address, + tokenName, + tokenVersion, + ) + if err != nil { + return x402.VerifyResponse{}, fmt.Errorf("failed to verify signature: %w", err) + } + + if !valid { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "invalid_exact_evm_payload_signature", + Payer: evmPayload.Authorization.From, + }, nil + } + + return x402.VerifyResponse{ + IsValid: true, + Payer: evmPayload.Authorization.From, + }, nil +} + +// Settle settles a payment on-chain (V1) +func (f *ExactEvmFacilitatorV1) Settle( + ctx context.Context, + payload x402.PaymentPayload, + requirements x402.PaymentRequirements, +) (x402.SettleResponse, error) { + // First verify the payment + verifyResp, err := f.Verify(ctx, payload, requirements) + if err != nil { + return x402.SettleResponse{}, err + } + if !verifyResp.IsValid { + return x402.SettleResponse{ + Success: false, + ErrorReason: verifyResp.InvalidReason, + Network: payload.Network, + }, nil + } + + // Parse EVM payload + evmPayload, err := evm.PayloadFromMap(payload.Payload) + if err != nil { + return x402.SettleResponse{ + Success: false, + ErrorReason: fmt.Sprintf("invalid payload: %v", err), + Network: payload.Network, + }, nil + } + + // Get asset info + networkStr := string(requirements.Network) + assetInfo, err := evm.GetAssetInfo(networkStr, requirements.Asset) + if err != nil { + return x402.SettleResponse{}, err + } + + // Parse signature components (v, r, s) + signatureBytes, err := evm.HexToBytes(evmPayload.Signature) + if err != nil { + return x402.SettleResponse{ + Success: false, + ErrorReason: "invalid signature format", + Network: payload.Network, + }, nil + } + + if len(signatureBytes) != 65 { + return x402.SettleResponse{ + Success: false, + ErrorReason: "invalid signature length", + Network: payload.Network, + }, nil + } + + r := signatureBytes[0:32] + s := signatureBytes[32:64] + v := signatureBytes[64] + + // Parse values + value, _ := new(big.Int).SetString(evmPayload.Authorization.Value, 10) + validAfter, _ := new(big.Int).SetString(evmPayload.Authorization.ValidAfter, 10) + validBefore, _ := new(big.Int).SetString(evmPayload.Authorization.ValidBefore, 10) + nonceBytes, _ := evm.HexToBytes(evmPayload.Authorization.Nonce) + + // Execute transferWithAuthorization + txHash, err := f.signer.WriteContract( + assetInfo.Address, + evm.TransferWithAuthorizationABI, + evm.FunctionTransferWithAuthorization, + evmPayload.Authorization.From, + evmPayload.Authorization.To, + value, + validAfter, + validBefore, + [32]byte(nonceBytes), + v, + [32]byte(r), + [32]byte(s), + ) + if err != nil { + return x402.SettleResponse{ + Success: false, + ErrorReason: fmt.Sprintf("transaction_failed: %v", err), + Network: payload.Network, + Payer: evmPayload.Authorization.From, + }, nil + } + + // Wait for transaction confirmation + receipt, err := f.signer.WaitForTransactionReceipt(txHash) + if err != nil { + return x402.SettleResponse{ + Success: false, + ErrorReason: fmt.Sprintf("failed to get receipt: %v", err), + Transaction: txHash, + Network: payload.Network, + Payer: evmPayload.Authorization.From, + }, nil + } + + if receipt.Status != evm.TxStatusSuccess { + return x402.SettleResponse{ + Success: false, + ErrorReason: "invalid_transaction_state", + Transaction: txHash, + Network: payload.Network, + Payer: evmPayload.Authorization.From, + }, nil + } + + return x402.SettleResponse{ + Success: true, + Transaction: txHash, + Network: payload.Network, + Payer: evmPayload.Authorization.From, + }, nil +} + +// verifySignature verifies the EIP-712 signature +func (f *ExactEvmFacilitatorV1) verifySignature( + ctx context.Context, + authorization evm.ExactEIP3009Authorization, + signature []byte, + chainID *big.Int, + verifyingContract string, + tokenName string, + tokenVersion string, +) (bool, error) { + // Create EIP-712 domain + domain := evm.TypedDataDomain{ + Name: tokenName, + Version: tokenVersion, + ChainID: chainID, + VerifyingContract: verifyingContract, + } + + // Define EIP-712 types + types := map[string][]evm.TypedDataField{ + "EIP712Domain": { + {Name: "name", Type: "string"}, + {Name: "version", Type: "string"}, + {Name: "chainId", Type: "uint256"}, + {Name: "verifyingContract", Type: "address"}, + }, + "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"}, + }, + } + + // Parse values for message + value, _ := new(big.Int).SetString(authorization.Value, 10) + validAfter, _ := new(big.Int).SetString(authorization.ValidAfter, 10) + validBefore, _ := new(big.Int).SetString(authorization.ValidBefore, 10) + nonceBytes, _ := evm.HexToBytes(authorization.Nonce) + + // Create message + message := map[string]interface{}{ + "from": authorization.From, + "to": authorization.To, + "value": value, + "validAfter": validAfter, + "validBefore": validBefore, + "nonce": nonceBytes, + } + + // Verify the signature + return f.signer.VerifyTypedData( + authorization.From, + domain, + types, + "TransferWithAuthorization", + message, + signature, + ) +} diff --git a/go/mechanisms/evm/v1/service.go b/go/mechanisms/evm/v1/service.go new file mode 100644 index 000000000..adaaafcee --- /dev/null +++ b/go/mechanisms/evm/v1/service.go @@ -0,0 +1,172 @@ +package v1 + +import ( + "context" + "fmt" + "math/big" + "strings" + "time" + + x402 "github.com/coinbase/x402-go/v2" + "github.com/coinbase/x402-go/v2/mechanisms/evm" +) + +// ExactEvmServiceV1 implements the SchemeNetworkService interface for EVM exact payments (V1) +type ExactEvmServiceV1 struct{} + +// NewExactEvmServiceV1 creates a new ExactEvmServiceV1 +func NewExactEvmServiceV1() *ExactEvmServiceV1 { + return &ExactEvmServiceV1{} +} + +// Scheme returns the scheme identifier +func (s *ExactEvmServiceV1) Scheme() string { + return evm.SchemeExact +} + +// ParsePrice parses a price into an AssetAmount (V1) +func (s *ExactEvmServiceV1) ParsePrice(price x402.Price, network x402.Network) (x402.AssetAmount, error) { + // Get network configuration + networkStr := string(network) + config, err := evm.GetNetworkConfig(networkStr) + if err != nil { + return x402.AssetAmount{}, err + } + + // V1 specific: Default to USDC for the network + defaultAsset := fmt.Sprintf("erc20:0x%s", strings.ToLower(config.DefaultAsset.Address)) + + // Handle different price types + switch p := price.(type) { + case string: + // Parse string format: "amount asset" + parts := strings.Fields(p) + if len(parts) == 1 { + // Just amount, use default asset + amount, err := evm.ParseAmount(parts[0], 6) // USDC has 6 decimals + if err != nil { + return x402.AssetAmount{}, fmt.Errorf("invalid amount: %w", err) + } + return x402.AssetAmount{ + Asset: defaultAsset, + Amount: amount.String(), + }, nil + } else if len(parts) == 2 { + // amount and asset + assetInfo, err := evm.GetAssetInfo(networkStr, parts[1]) + if err != nil { + return x402.AssetAmount{}, err + } + amount, err := evm.ParseAmount(parts[0], assetInfo.Decimals) + if err != nil { + return x402.AssetAmount{}, fmt.Errorf("invalid amount: %w", err) + } + return x402.AssetAmount{ + Asset: fmt.Sprintf("erc20:0x%s", strings.ToLower(assetInfo.Address)), + Amount: amount.String(), + }, nil + } + return x402.AssetAmount{}, fmt.Errorf("invalid price format: %s", p) + + case float64: + // V1 specific: Treat as USD amount in USDC + amount, err := evm.ParseAmount(fmt.Sprintf("%.6f", p), 6) + if err != nil { + return x402.AssetAmount{}, fmt.Errorf("invalid amount: %w", err) + } + return x402.AssetAmount{ + Asset: defaultAsset, + Amount: amount.String(), + }, nil + + case int: + // V1 specific: Treat as USD amount in USDC + amount, err := evm.ParseAmount(fmt.Sprintf("%d", p), 6) + if err != nil { + return x402.AssetAmount{}, fmt.Errorf("invalid amount: %w", err) + } + return x402.AssetAmount{ + Asset: defaultAsset, + Amount: amount.String(), + }, nil + + case map[string]interface{}: + // Handle object format: {asset: string, amount: string} + assetStr, ok := p["asset"].(string) + if !ok { + assetStr = defaultAsset + } + amountStr, ok := p["amount"].(string) + if !ok { + return x402.AssetAmount{}, fmt.Errorf("missing amount in price object") + } + + // Parse asset info to get decimals + assetInfo, err := evm.GetAssetInfo(networkStr, assetStr) + if err != nil { + return x402.AssetAmount{}, err + } + + amount, err := evm.ParseAmount(amountStr, assetInfo.Decimals) + if err != nil { + return x402.AssetAmount{}, fmt.Errorf("invalid amount: %w", err) + } + + return x402.AssetAmount{ + Asset: fmt.Sprintf("erc20:0x%s", strings.ToLower(assetInfo.Address)), + Amount: amount.String(), + }, nil + + default: + return x402.AssetAmount{}, fmt.Errorf("unsupported price type: %T", price) + } +} + +// EnhancePaymentRequirements enhances payment requirements with EVM-specific details (V1) +func (s *ExactEvmServiceV1) EnhancePaymentRequirements( + ctx context.Context, + requirements x402.PaymentRequirements, + supportedKind x402.SupportedKind, + extensionKeys []string, +) (x402.PaymentRequirements, error) { + // V1 specific: only handle version 1 + if supportedKind.X402Version != 1 { + return requirements, fmt.Errorf("v1 only supports x402 version 1") + } + + // Ensure extra map exists + if requirements.Extra == nil { + requirements.Extra = make(map[string]interface{}) + } + + // Get network configuration + networkStr := string(requirements.Network) + config, err := evm.GetNetworkConfig(networkStr) + if err != nil { + return requirements, err + } + + // Get asset info + assetInfo, err := evm.GetAssetInfo(networkStr, requirements.Asset) + if err != nil { + return requirements, err + } + + // V1 specific: Set EIP-712 domain parameters + requirements.Extra["name"] = assetInfo.Name + requirements.Extra["version"] = assetInfo.Version + requirements.Extra["chainId"] = config.ChainID.String() + requirements.Extra["verifyingContract"] = assetInfo.Address + + // V1 specific: Add 10-minute validity window hint + now := time.Now().Unix() + requirements.Extra["validAfter"] = fmt.Sprintf("%d", now-600) // 10 minutes ago + requirements.Extra["validBefore"] = fmt.Sprintf("%d", now+600) // 10 minutes from now + + // Add display amount for UI + amount, _ := new(big.Int).SetString(requirements.Amount, 10) + displayAmount := evm.FormatAmount(amount, assetInfo.Decimals) + requirements.Extra["displayAmount"] = fmt.Sprintf("%s %s", displayAmount, assetInfo.Name) + + return requirements, nil +} diff --git a/go/service.go b/go/service.go new file mode 100644 index 000000000..06c3793cb --- /dev/null +++ b/go/service.go @@ -0,0 +1,473 @@ +package x402 + +import ( + "context" + "fmt" + "sync" + "time" +) + +// x402ResourceService manages payment requirements and verification for protected resources +// This is used by servers/APIs that want to charge for access +type x402ResourceService struct { + mu sync.RWMutex + + // Map of network -> scheme -> service implementation + schemes map[Network]map[string]SchemeNetworkService + + // Facilitator clients for payment verification/settlement + facilitatorClients []FacilitatorClient + + // Cache of supported payment kinds from facilitators + supportedCache *SupportedCache + + // Map of version -> network -> scheme -> FacilitatorClient + // Built during Initialize() to map which facilitator handles which payment type + facilitatorClientsMap map[int]map[Network]map[string]FacilitatorClient +} + +// SupportedCache caches facilitator capabilities +type SupportedCache struct { + mu sync.RWMutex + data map[string]SupportedResponse // key is facilitator identifier + expiry map[string]time.Time + ttl time.Duration +} + +// ResourceServiceOption configures the service +type ResourceServiceOption func(*x402ResourceService) + +// WithFacilitatorClient adds a facilitator client +func WithFacilitatorClient(client FacilitatorClient) ResourceServiceOption { + return func(s *x402ResourceService) { + s.facilitatorClients = append(s.facilitatorClients, client) + } +} + +// WithSchemeService registers a scheme service implementation +func WithSchemeService(network Network, service SchemeNetworkService) ResourceServiceOption { + return func(s *x402ResourceService) { + s.registerScheme(network, service) + } +} + +// WithCacheTTL sets the cache TTL for supported kinds +func WithCacheTTL(ttl time.Duration) ResourceServiceOption { + return func(s *x402ResourceService) { + s.supportedCache.ttl = ttl + } +} + +// Newx402ResourceService creates a new resource service +func Newx402ResourceService(opts ...ResourceServiceOption) *x402ResourceService { + s := &x402ResourceService{ + schemes: make(map[Network]map[string]SchemeNetworkService), + facilitatorClients: []FacilitatorClient{}, + supportedCache: &SupportedCache{ + data: make(map[string]SupportedResponse), + expiry: make(map[string]time.Time), + ttl: 5 * time.Minute, // Default 5 minute cache + }, + facilitatorClientsMap: make(map[int]map[Network]map[string]FacilitatorClient), + } + + for _, opt := range opts { + opt(s) + } + + // If no facilitator clients provided, this is an error for production + // but we'll allow it for testing + if len(s.facilitatorClients) == 0 { + // Log warning - in production should have at least one facilitator + } + + return s +} + +// Initialize fetches supported payment kinds from all facilitators +// Should be called on startup to populate cache and build facilitator mapping +func (s *x402ResourceService) Initialize(ctx context.Context) error { + s.mu.Lock() + defer s.mu.Unlock() + + // Clear existing mappings + s.facilitatorClientsMap = make(map[int]map[Network]map[string]FacilitatorClient) + + var lastErr error + successCount := 0 + + // Process facilitators in order (earlier ones get precedence) + for i, client := range s.facilitatorClients { + supported, err := client.GetSupported(ctx) + if err != nil { + lastErr = fmt.Errorf("facilitator %d: %w", i, err) + continue + } + + // Cache the supported kinds + key := fmt.Sprintf("facilitator_%d", i) + s.supportedCache.Set(key, supported) + successCount++ + + // Build the facilitatorClientsMap for quick lookup + for _, kind := range supported.Kinds { + // Get or create version map + if s.facilitatorClientsMap[kind.X402Version] == nil { + s.facilitatorClientsMap[kind.X402Version] = make(map[Network]map[string]FacilitatorClient) + } + versionMap := s.facilitatorClientsMap[kind.X402Version] + + // Get or create network map + if versionMap[kind.Network] == nil { + versionMap[kind.Network] = make(map[string]FacilitatorClient) + } + networkMap := versionMap[kind.Network] + + // Only store if not already present (gives precedence to earlier facilitators) + if _, exists := networkMap[kind.Scheme]; !exists { + networkMap[kind.Scheme] = client + } + } + } + + if successCount == 0 && lastErr != nil { + return fmt.Errorf("failed to initialize any facilitators: %w", lastErr) + } + + return nil +} + +// RegisterScheme registers a scheme service for a network +func (s *x402ResourceService) RegisterScheme(network Network, service SchemeNetworkService) *x402ResourceService { + return s.registerScheme(network, service) +} + +func (s *x402ResourceService) registerScheme(network Network, service SchemeNetworkService) *x402ResourceService { + s.mu.Lock() + defer s.mu.Unlock() + + if s.schemes[network] == nil { + s.schemes[network] = make(map[string]SchemeNetworkService) + } + + s.schemes[network][service.Scheme()] = service + + return s +} + +// BuildPaymentRequirements creates payment requirements for a resource +func (s *x402ResourceService) BuildPaymentRequirements(ctx context.Context, config ResourceConfig) ([]PaymentRequirements, error) { + s.mu.RLock() + defer s.mu.RUnlock() + + // Find the scheme service + service := findByNetworkAndScheme(s.schemes, config.Scheme, config.Network) + if service == nil { + return nil, &PaymentError{ + Code: ErrCodeUnsupportedScheme, + Message: fmt.Sprintf("no service registered for scheme %s on network %s", config.Scheme, config.Network), + } + } + + // Get supported kinds from facilitators + supportedKind := s.findSupportedKind(ProtocolVersion, config.Network, config.Scheme) + if supportedKind == nil { + return nil, &PaymentError{ + Code: ErrCodeUnsupportedNetwork, + Message: fmt.Sprintf("facilitator does not support %s on %s", config.Scheme, config.Network), + Details: map[string]interface{}{ + "hint": "call Initialize() to fetch supported kinds from facilitators", + }, + } + } + + // Parse the price using the scheme's parser + assetAmount, err := service.ParsePrice(config.Price, config.Network) + if err != nil { + return nil, fmt.Errorf("failed to parse price: %w", err) + } + + // Build base requirements + baseRequirements := PaymentRequirements{ + Scheme: config.Scheme, + Network: config.Network, + Asset: assetAmount.Asset, + Amount: assetAmount.Amount, + PayTo: config.PayTo, + MaxTimeoutSeconds: config.MaxTimeoutSeconds, + Extra: assetAmount.Extra, + } + + // Set default timeout if not specified + if baseRequirements.MaxTimeoutSeconds == 0 { + baseRequirements.MaxTimeoutSeconds = 300 // 5 minutes default + } + + // Get facilitator extensions + extensions := s.getFacilitatorExtensions(ProtocolVersion, config.Network, config.Scheme) + + // Enhance with scheme-specific details + enhanced, err := service.EnhancePaymentRequirements(ctx, baseRequirements, *supportedKind, extensions) + if err != nil { + return nil, fmt.Errorf("failed to enhance payment requirements: %w", err) + } + + return []PaymentRequirements{enhanced}, nil +} + +// CreatePaymentRequiredResponse creates a 402 response +func (s *x402ResourceService) CreatePaymentRequiredResponse( + requirements []PaymentRequirements, + info ResourceInfo, + errorMsg string, + extensions map[string]interface{}, +) PaymentRequired { + response := PaymentRequired{ + X402Version: ProtocolVersion, + Error: errorMsg, + Resource: &info, + Accepts: requirements, + Extensions: extensions, + } + + if errorMsg == "" { + response.Error = "Payment required" + } + + return response +} + +// VerifyPayment verifies a payment against requirements +func (s *x402ResourceService) VerifyPayment(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (VerifyResponse, error) { + // Validate inputs + if err := ValidatePaymentPayload(payload); err != nil { + return VerifyResponse{IsValid: false, InvalidReason: err.Error()}, err + } + + if err := ValidatePaymentRequirements(requirements); err != nil { + return VerifyResponse{IsValid: false, InvalidReason: err.Error()}, err + } + + // Find appropriate facilitator + facilitator := s.findFacilitatorForPayment(payload.X402Version, requirements.Network, requirements.Scheme) + if facilitator == nil { + // Try all facilitators as fallback + for _, client := range s.facilitatorClients { + resp, err := client.Verify(ctx, payload, requirements) + if err == nil { + return resp, nil + } + } + + return VerifyResponse{ + IsValid: false, + InvalidReason: "no facilitator available for verification", + }, &PaymentError{ + Code: ErrCodeUnsupportedNetwork, + Message: "no facilitator supports this payment type", + } + } + + return facilitator.Verify(ctx, payload, requirements) +} + +// SettlePayment settles a verified payment +func (s *x402ResourceService) SettlePayment(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (SettleResponse, error) { + // Find appropriate facilitator + facilitator := s.findFacilitatorForPayment(payload.X402Version, requirements.Network, requirements.Scheme) + if facilitator == nil { + // Try all facilitators as fallback + for _, client := range s.facilitatorClients { + resp, err := client.Settle(ctx, payload, requirements) + if err == nil { + return resp, nil + } + } + + return SettleResponse{ + Success: false, + ErrorReason: "no facilitator available for settlement", + }, &PaymentError{ + Code: ErrCodeSettlementFailed, + Message: "no facilitator supports this payment type", + } + } + + return facilitator.Settle(ctx, payload, requirements) +} + +// FindMatchingRequirements finds requirements that match a payment payload +func (s *x402ResourceService) FindMatchingRequirements(available []PaymentRequirements, payload PaymentPayload) *PaymentRequirements { + switch payload.X402Version { + case 2: + // V2: match by accepted requirements + for _, req := range available { + if DeepEqual(req, payload.Accepted) { + return &req + } + } + case 1: + // V1: match by scheme and network + for _, req := range available { + if req.Scheme == payload.Scheme && req.Network == payload.Network { + return &req + } + } + } + return nil +} + +// ProcessPaymentRequest processes a payment request end-to-end +func (s *x402ResourceService) ProcessPaymentRequest( + ctx context.Context, + paymentPayload *PaymentPayload, + resourceConfig ResourceConfig, + resourceInfo ResourceInfo, + extensions map[string]interface{}, +) (*ProcessResult, error) { + requirements, err := s.BuildPaymentRequirements(ctx, resourceConfig) + if err != nil { + return nil, err + } + + if paymentPayload == nil { + return &ProcessResult{ + Success: false, + RequiresPayment: &PaymentRequired{ + X402Version: ProtocolVersion, + Error: "Payment required", + Resource: &resourceInfo, + Accepts: requirements, + Extensions: extensions, + }, + }, nil + } + + // Find matching requirements + matchingRequirements := s.FindMatchingRequirements(requirements, *paymentPayload) + if matchingRequirements == nil { + return &ProcessResult{ + Success: false, + RequiresPayment: &PaymentRequired{ + X402Version: ProtocolVersion, + Error: "No matching payment requirements found", + Resource: &resourceInfo, + Accepts: requirements, + Extensions: extensions, + }, + }, nil + } + + // Verify payment + verificationResult, err := s.VerifyPayment(ctx, *paymentPayload, *matchingRequirements) + if err != nil { + return nil, err + } + + if !verificationResult.IsValid { + return &ProcessResult{ + Success: false, + Error: verificationResult.InvalidReason, + VerificationResult: &verificationResult, + }, nil + } + + // Payment verified, ready for settlement + return &ProcessResult{ + Success: true, + VerificationResult: &verificationResult, + }, nil +} + +// ProcessResult contains the result of processing a payment request +type ProcessResult struct { + Success bool + RequiresPayment *PaymentRequired + VerificationResult *VerifyResponse + SettlementResult *SettleResponse + Error string +} + +// Helper methods + +// findSupportedKind finds a supported kind from cache +func (s *x402ResourceService) findSupportedKind(version int, network Network, scheme string) *SupportedKind { + s.supportedCache.mu.RLock() + defer s.supportedCache.mu.RUnlock() + + for key, supported := range s.supportedCache.data { + // Check if cache entry is still valid + if expiry, exists := s.supportedCache.expiry[key]; exists { + if time.Now().After(expiry) { + continue // Skip expired entries + } + } + + // Look for matching kind + for _, kind := range supported.Kinds { + if kind.X402Version == version && + kind.Scheme == scheme && + Network(kind.Network).Match(network) { + return &SupportedKind{ + X402Version: kind.X402Version, + Scheme: kind.Scheme, + Network: kind.Network, + Extra: kind.Extra, + } + } + } + } + + return nil +} + +// getFacilitatorExtensions gets extensions for a payment type +func (s *x402ResourceService) getFacilitatorExtensions(version int, network Network, scheme string) []string { + s.supportedCache.mu.RLock() + defer s.supportedCache.mu.RUnlock() + + for _, supported := range s.supportedCache.data { + for _, kind := range supported.Kinds { + if kind.X402Version == version && + kind.Scheme == scheme && + Network(kind.Network).Match(network) { + return supported.Extensions + } + } + } + + return []string{} +} + +// findFacilitatorForPayment finds the facilitator that supports a payment type +// Uses the facilitatorClientsMap built during Initialize() for O(1) lookup +func (s *x402ResourceService) findFacilitatorForPayment(version int, network Network, scheme string) FacilitatorClient { + s.mu.RLock() + defer s.mu.RUnlock() + + versionMap, exists := s.facilitatorClientsMap[version] + if !exists { + return nil + } + + // Use the utility function to find with pattern matching support + return findByNetworkAndScheme(versionMap, scheme, network) +} + +// Set adds an item to the cache +func (c *SupportedCache) Set(key string, value SupportedResponse) { + c.mu.Lock() + defer c.mu.Unlock() + + c.data[key] = value + c.expiry[key] = time.Now().Add(c.ttl) +} + +// Clear clears the cache +func (c *SupportedCache) Clear() { + c.mu.Lock() + defer c.mu.Unlock() + + c.data = make(map[string]SupportedResponse) + c.expiry = make(map[string]time.Time) +} diff --git a/go/service_test.go b/go/service_test.go new file mode 100644 index 000000000..6be5ea241 --- /dev/null +++ b/go/service_test.go @@ -0,0 +1,611 @@ +package x402 + +import ( + "context" + "errors" + "testing" + "time" +) + +// Mock service for testing +type mockSchemeNetworkService struct { + scheme string + parsePrice func(price Price, network Network) (AssetAmount, error) + enhanceReqs func(ctx context.Context, base PaymentRequirements, supported SupportedKind, extensions []string) (PaymentRequirements, error) +} + +func (m *mockSchemeNetworkService) Scheme() string { + return m.scheme +} + +func (m *mockSchemeNetworkService) ParsePrice(price Price, network Network) (AssetAmount, error) { + if m.parsePrice != nil { + return m.parsePrice(price, network) + } + return AssetAmount{ + Asset: "USDC", + Amount: "1000000", + Extra: map[string]interface{}{}, + }, nil +} + +func (m *mockSchemeNetworkService) EnhancePaymentRequirements(ctx context.Context, base PaymentRequirements, supported SupportedKind, extensions []string) (PaymentRequirements, error) { + if m.enhanceReqs != nil { + return m.enhanceReqs(ctx, base, supported, extensions) + } + enhanced := base + enhanced.Extra = map[string]interface{}{ + "enhanced": true, + } + return enhanced, nil +} + +// Mock facilitator client for testing +type mockFacilitatorClient struct { + identifier string + verify func(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (VerifyResponse, error) + settle func(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (SettleResponse, error) + supported func(ctx context.Context) (SupportedResponse, error) +} + +func (m *mockFacilitatorClient) Verify(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (VerifyResponse, error) { + if m.verify != nil { + return m.verify(ctx, payload, requirements) + } + return VerifyResponse{IsValid: true, Payer: "0xpayer"}, nil +} + +func (m *mockFacilitatorClient) Settle(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (SettleResponse, error) { + if m.settle != nil { + return m.settle(ctx, payload, requirements) + } + return SettleResponse{Success: true, Transaction: "0xtx"}, nil +} + +func (m *mockFacilitatorClient) GetSupported(ctx context.Context) (SupportedResponse, error) { + if m.supported != nil { + return m.supported(ctx) + } + return SupportedResponse{ + Kinds: []SupportedKind{ + { + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + Extra: map[string]interface{}{}, + }, + }, + Extensions: []string{}, + }, nil +} + +func (m *mockFacilitatorClient) Identifier() string { + if m.identifier != "" { + return m.identifier + } + return "mock" +} + +func TestNewx402ResourceService(t *testing.T) { + service := Newx402ResourceService() + if service == nil { + t.Fatal("Expected service to be created") + } + if service.schemes == nil { + t.Fatal("Expected schemes map to be initialized") + } + if service.facilitatorClients == nil { + t.Fatal("Expected facilitator clients to be initialized") + } + if service.supportedCache == nil { + t.Fatal("Expected cache to be initialized") + } +} + +func TestServiceWithOptions(t *testing.T) { + mockClient := &mockFacilitatorClient{} + mockService := &mockSchemeNetworkService{scheme: "exact"} + + service := Newx402ResourceService( + WithFacilitatorClient(mockClient), + WithSchemeService("eip155:1", mockService), + WithCacheTTL(10*time.Minute), + ) + + if len(service.facilitatorClients) != 1 { + t.Fatal("Expected 1 facilitator client") + } + if service.schemes["eip155:1"]["exact"] != mockService { + t.Fatal("Expected scheme service to be registered") + } + if service.supportedCache.ttl != 10*time.Minute { + t.Fatal("Expected cache TTL to be set") + } +} + +func TestServiceInitialize(t *testing.T) { + ctx := context.Background() + mockClient := &mockFacilitatorClient{ + supported: func(ctx context.Context) (SupportedResponse, error) { + return SupportedResponse{ + Kinds: []SupportedKind{ + { + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + }, + { + X402Version: 2, + Scheme: "transfer", + Network: "eip155:8453", + }, + }, + Extensions: []string{"bazaar"}, + }, nil + }, + } + + service := Newx402ResourceService(WithFacilitatorClient(mockClient)) + err := service.Initialize(ctx) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + // Check that facilitatorClientsMap was built + if len(service.facilitatorClientsMap) != 1 { + t.Fatal("Expected 1 version in map") + } + if len(service.facilitatorClientsMap[2]) != 2 { + t.Fatal("Expected 2 networks for v2") + } + if service.facilitatorClientsMap[2]["eip155:1"]["exact"] != mockClient { + t.Fatal("Expected client to be mapped for exact scheme") + } + if service.facilitatorClientsMap[2]["eip155:8453"]["transfer"] != mockClient { + t.Fatal("Expected client to be mapped for transfer scheme") + } +} + +func TestServiceInitializeWithMultipleFacilitators(t *testing.T) { + ctx := context.Background() + + // First facilitator supports exact on mainnet + mockClient1 := &mockFacilitatorClient{ + identifier: "facilitator1", + supported: func(ctx context.Context) (SupportedResponse, error) { + return SupportedResponse{ + Kinds: []SupportedKind{ + { + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + }, + }, + }, nil + }, + } + + // Second facilitator supports exact on Base (should not override mainnet) + mockClient2 := &mockFacilitatorClient{ + identifier: "facilitator2", + supported: func(ctx context.Context) (SupportedResponse, error) { + return SupportedResponse{ + Kinds: []SupportedKind{ + { + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", // Same as first + }, + { + X402Version: 2, + Scheme: "exact", + Network: "eip155:8453", // New network + }, + }, + }, nil + }, + } + + service := Newx402ResourceService( + WithFacilitatorClient(mockClient1), + WithFacilitatorClient(mockClient2), + ) + + err := service.Initialize(ctx) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + // First facilitator should have precedence for eip155:1 + if service.facilitatorClientsMap[2]["eip155:1"]["exact"] != mockClient1 { + t.Fatal("Expected first facilitator to have precedence") + } + + // Second facilitator should handle eip155:8453 + if service.facilitatorClientsMap[2]["eip155:8453"]["exact"] != mockClient2 { + t.Fatal("Expected second facilitator for new network") + } +} + +func TestServiceBuildPaymentRequirements(t *testing.T) { + ctx := context.Background() + + mockService := &mockSchemeNetworkService{ + scheme: "exact", + parsePrice: func(price Price, network Network) (AssetAmount, error) { + return AssetAmount{ + Asset: "USDC", + Amount: "5000000", + Extra: map[string]interface{}{"decimals": 6}, + }, nil + }, + } + + mockClient := &mockFacilitatorClient{} + + service := Newx402ResourceService( + WithFacilitatorClient(mockClient), + WithSchemeService("eip155:1", mockService), + ) + + // Initialize to populate supported kinds + service.Initialize(ctx) + + config := ResourceConfig{ + Scheme: "exact", + PayTo: "0xrecipient", + Price: "$5.00", + Network: "eip155:1", + MaxTimeoutSeconds: 600, + } + + requirements, err := service.BuildPaymentRequirements(ctx, config) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + if len(requirements) != 1 { + t.Fatal("Expected 1 requirement") + } + + req := requirements[0] + if req.Scheme != "exact" { + t.Fatalf("Expected scheme 'exact', got %s", req.Scheme) + } + if req.Amount != "5000000" { + t.Fatalf("Expected amount '5000000', got %s", req.Amount) + } + if req.Asset != "USDC" { + t.Fatalf("Expected asset 'USDC', got %s", req.Asset) + } + if req.MaxTimeoutSeconds != 600 { + t.Fatalf("Expected timeout 600, got %d", req.MaxTimeoutSeconds) + } + if req.Extra["enhanced"] != true { + t.Fatal("Expected requirements to be enhanced") + } +} + +func TestServiceBuildPaymentRequirementsNoScheme(t *testing.T) { + ctx := context.Background() + service := Newx402ResourceService() + + config := ResourceConfig{ + Scheme: "unregistered", + PayTo: "0xrecipient", + Price: "$5.00", + Network: "eip155:1", + } + + _, err := service.BuildPaymentRequirements(ctx, config) + if err == nil { + t.Fatal("Expected error for unregistered scheme") + } + + var paymentErr *PaymentError + if !errors.As(err, &paymentErr) || paymentErr.Code != ErrCodeUnsupportedScheme { + t.Fatal("Expected UnsupportedScheme error") + } +} + +func TestServiceCreatePaymentRequiredResponse(t *testing.T) { + service := Newx402ResourceService() + + requirements := []PaymentRequirements{ + { + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + }, + } + + info := ResourceInfo{ + URL: "https://api.example.com/resource", + Description: "Premium API access", + MimeType: "application/json", + } + + response := service.CreatePaymentRequiredResponse( + requirements, + info, + "Custom error message", + map[string]interface{}{"custom": "extension"}, + ) + + if response.X402Version != 2 { + t.Fatalf("Expected version 2, got %d", response.X402Version) + } + if response.Error != "Custom error message" { + t.Fatalf("Expected custom error, got %s", response.Error) + } + if response.Resource.URL != info.URL { + t.Fatal("Expected resource info to be set") + } + if len(response.Accepts) != 1 { + t.Fatal("Expected 1 requirement") + } + if response.Extensions["custom"] != "extension" { + t.Fatal("Expected custom extension") + } +} + +func TestServiceVerifyPayment(t *testing.T) { + ctx := context.Background() + + mockClient := &mockFacilitatorClient{ + verify: func(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (VerifyResponse, error) { + return VerifyResponse{ + IsValid: true, + Payer: "0xverifiedpayer", + }, nil + }, + } + + service := Newx402ResourceService(WithFacilitatorClient(mockClient)) + service.Initialize(ctx) + + payload := PaymentPayload{ + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + Payload: map[string]interface{}{}, + } + + requirements := PaymentRequirements{ + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + } + + response, err := service.VerifyPayment(ctx, payload, requirements) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if !response.IsValid { + t.Fatal("Expected valid verification") + } + if response.Payer != "0xverifiedpayer" { + t.Fatalf("Expected payer '0xverifiedpayer', got %s", response.Payer) + } +} + +func TestServiceSettlePayment(t *testing.T) { + ctx := context.Background() + + mockClient := &mockFacilitatorClient{ + settle: func(ctx context.Context, payload PaymentPayload, requirements PaymentRequirements) (SettleResponse, error) { + return SettleResponse{ + Success: true, + Transaction: "0xsettledtx", + Payer: "0xpayer", + }, nil + }, + } + + service := Newx402ResourceService(WithFacilitatorClient(mockClient)) + service.Initialize(ctx) + + payload := PaymentPayload{ + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + Payload: map[string]interface{}{}, + } + + requirements := PaymentRequirements{ + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + } + + response, err := service.SettlePayment(ctx, payload, requirements) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if !response.Success { + t.Fatal("Expected successful settlement") + } + if response.Transaction != "0xsettledtx" { + t.Fatalf("Expected transaction '0xsettledtx', got %s", response.Transaction) + } +} + +func TestServiceFindMatchingRequirements(t *testing.T) { + service := Newx402ResourceService() + + available := []PaymentRequirements{ + { + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient1", + }, + { + Scheme: "transfer", + Network: "eip155:8453", + Asset: "USDC", + Amount: "2000000", + PayTo: "0xrecipient2", + }, + } + + // Test v2 matching (by accepted) + payloadV2 := PaymentPayload{ + X402Version: 2, + Accepted: PaymentRequirements{ + Scheme: "transfer", + Network: "eip155:8453", + Asset: "USDC", + Amount: "2000000", + PayTo: "0xrecipient2", + }, + } + + matched := service.FindMatchingRequirements(available, payloadV2) + if matched == nil { + t.Fatal("Expected match for v2") + } + if matched.Scheme != "transfer" { + t.Fatal("Expected transfer scheme to match") + } + + // Test v1 matching (by scheme/network) + payloadV1 := PaymentPayload{ + X402Version: 1, + Scheme: "exact", + Network: "eip155:1", + } + + matched = service.FindMatchingRequirements(available, payloadV1) + if matched == nil { + t.Fatal("Expected match for v1") + } + if matched.PayTo != "0xrecipient1" { + t.Fatal("Expected first requirement to match") + } + + // Test no match + payloadNoMatch := PaymentPayload{ + X402Version: 2, + Accepted: PaymentRequirements{ + Scheme: "nonexistent", + Network: "eip155:1", + Asset: "USDC", + Amount: "3000000", + PayTo: "0xrecipient3", + }, + } + + matched = service.FindMatchingRequirements(available, payloadNoMatch) + if matched != nil { + t.Fatal("Expected no match") + } +} + +func TestServiceProcessPaymentRequest(t *testing.T) { + ctx := context.Background() + + mockService := &mockSchemeNetworkService{scheme: "exact"} + mockClient := &mockFacilitatorClient{} + + service := Newx402ResourceService( + WithFacilitatorClient(mockClient), + WithSchemeService("eip155:1", mockService), + ) + service.Initialize(ctx) + + config := ResourceConfig{ + Scheme: "exact", + PayTo: "0xrecipient", + Price: "$1.00", + Network: "eip155:1", + } + + info := ResourceInfo{ + URL: "https://api.example.com/resource", + Description: "API resource", + } + + // Test without payment (should require payment) + result, err := service.ProcessPaymentRequest(ctx, nil, config, info, nil) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if result.Success { + t.Fatal("Expected payment to be required") + } + if result.RequiresPayment == nil { + t.Fatal("Expected payment required response") + } + + // Test with valid payment + // First, build requirements to see what they actually are + builtReqs, _ := service.BuildPaymentRequirements(ctx, config) + + payload := &PaymentPayload{ + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + Payload: map[string]interface{}{}, + Accepted: builtReqs[0], // Use the actual built requirements + } + + result, err = service.ProcessPaymentRequest(ctx, payload, config, info, nil) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if !result.Success { + if result.Error != "" { + t.Fatalf("Expected payment to be verified, got error: %s", result.Error) + } + if result.RequiresPayment != nil { + t.Fatalf("Expected payment to be verified, got payment required: %v", result.RequiresPayment.Error) + } + t.Fatal("Expected payment to be verified") + } + if result.VerificationResult == nil { + t.Fatal("Expected verification result") + } + if !result.VerificationResult.IsValid { + t.Fatal("Expected valid verification") + } +} + +func TestSupportedCache(t *testing.T) { + cache := &SupportedCache{ + data: make(map[string]SupportedResponse), + expiry: make(map[string]time.Time), + ttl: 100 * time.Millisecond, + } + + response := SupportedResponse{ + Kinds: []SupportedKind{ + {X402Version: 2, Scheme: "exact", Network: "eip155:1"}, + }, + } + + // Set and verify + cache.Set("test", response) + if len(cache.data) != 1 { + t.Fatal("Expected item in cache") + } + + // Wait for expiry + time.Sleep(150 * time.Millisecond) + + // Clear cache + cache.Clear() + if len(cache.data) != 0 { + t.Fatal("Expected cache to be cleared") + } + if len(cache.expiry) != 0 { + t.Fatal("Expected expiry map to be cleared") + } +} diff --git a/go/test/integration/core_test.go b/go/test/integration/core_test.go new file mode 100644 index 000000000..e51cf5b8b --- /dev/null +++ b/go/test/integration/core_test.go @@ -0,0 +1,95 @@ +package integration_test + +import ( + "context" + "testing" + + x402 "github.com/coinbase/x402-go/v2" + "github.com/coinbase/x402-go/v2/test/mocks/cash" +) + +// TestCoreIntegration tests the integration between x402Client, x402ResourceService, and x402Facilitator +func TestCoreIntegration(t *testing.T) { + t.Run("Cash Flow - x402Client / x402ResourceService / x402Facilitator", func(t *testing.T) { + ctx := context.Background() + + // Setup client with cash scheme + client := x402.Newx402Client() + client.RegisterScheme("x402:cash", cash.NewSchemeNetworkClient("John")) + + // Setup facilitator with cash scheme + facilitator := x402.Newx402Facilitator() + facilitator.RegisterScheme("x402:cash", cash.NewSchemeNetworkFacilitator()) + + // Create facilitator client wrapper + facilitatorClient := cash.NewFacilitatorClient(facilitator) + + // Setup resource service + service := x402.Newx402ResourceService( + x402.WithFacilitatorClient(facilitatorClient), + ) + service.RegisterScheme("x402:cash", cash.NewSchemeNetworkService()) + + // Initialize service to fetch supported kinds + err := service.Initialize(ctx) + if err != nil { + t.Fatalf("Failed to initialize service: %v", err) + } + + // Server - builds PaymentRequired response + accepts := []x402.PaymentRequirements{ + cash.BuildPaymentRequirements("Company Co.", "USD", "1"), + } + resource := x402.ResourceInfo{ + URL: "https://company.co", + Description: "Company Co. resource", + MimeType: "application/json", + } + paymentRequiredResponse := service.CreatePaymentRequiredResponse(accepts, resource, "", nil) + + // Client - responds with PaymentPayload response + selected, err := client.SelectPaymentRequirements(paymentRequiredResponse.X402Version, accepts) + if err != nil { + t.Fatalf("Failed to select payment requirements: %v", err) + } + + paymentPayload, err := client.CreatePaymentPayload(ctx, paymentRequiredResponse.X402Version, selected) + if err != nil { + t.Fatalf("Failed to create payment payload: %v", err) + } + + // Server - maps payment payload to payment requirements + accepted := service.FindMatchingRequirements(accepts, paymentPayload) + if accepted == nil { + t.Fatal("No matching payment requirements found") + } + + // Server - verifies payment + verifyResponse, err := service.VerifyPayment(ctx, paymentPayload, *accepted) + if err != nil { + t.Fatalf("Failed to verify payment: %v", err) + } + + if !verifyResponse.IsValid { + t.Fatalf("Payment verification failed: %s", verifyResponse.InvalidReason) + } + + // Server does work here... + + // Server - settles payment + settleResponse, err := service.SettlePayment(ctx, paymentPayload, *accepted) + if err != nil { + t.Fatalf("Failed to settle payment: %v", err) + } + + if !settleResponse.Success { + t.Fatalf("Payment settlement failed: %s", settleResponse.ErrorReason) + } + + // Verify the transaction message + expectedTransaction := "John transferred 1 USD to Company Co." + if settleResponse.Transaction != expectedTransaction { + t.Errorf("Expected transaction '%s', got '%s'", expectedTransaction, settleResponse.Transaction) + } + }) +} diff --git a/go/test/integration/evm_test.go b/go/test/integration/evm_test.go new file mode 100644 index 000000000..31a458757 --- /dev/null +++ b/go/test/integration/evm_test.go @@ -0,0 +1,630 @@ +// Package integration_test contains integration tests for the x402 Go SDK. +// This file specifically tests the EVM mechanism integration with both V1 and V2 implementations. +package integration_test + +import ( + "context" + "math/big" + "testing" + + x402 "github.com/coinbase/x402-go/v2" + "github.com/coinbase/x402-go/v2/mechanisms/evm" + evmv1 "github.com/coinbase/x402-go/v2/mechanisms/evm/v1" +) + +// Mock EVM signer for client +type mockClientEvmSigner struct { + address string +} + +func (m *mockClientEvmSigner) Address() string { + if m.address == "" { + return "0x1234567890123456789012345678901234567890" + } + return m.address +} + +func (m *mockClientEvmSigner) SignTypedData( + domain evm.TypedDataDomain, + types map[string][]evm.TypedDataField, + primaryType string, + message map[string]interface{}, +) ([]byte, error) { + // Return a mock signature (65 bytes) + sig := make([]byte, 65) + // Set v to 27 (common value for Ethereum signatures) + sig[64] = 27 + return sig, nil +} + +// Mock EVM signer for facilitator +type mockFacilitatorEvmSigner struct { + balances map[string]*big.Int + nonces map[string]bool +} + +func newMockFacilitatorEvmSigner() *mockFacilitatorEvmSigner { + return &mockFacilitatorEvmSigner{ + balances: make(map[string]*big.Int), + nonces: make(map[string]bool), + } +} + +func (m *mockFacilitatorEvmSigner) Address() string { + return "0xfacilitator1234567890123456789012345678" +} + +func (m *mockFacilitatorEvmSigner) GetBalance(address string, tokenAddress string) (*big.Int, error) { + key := address + ":" + tokenAddress + if balance, ok := m.balances[key]; ok { + return balance, nil + } + // Default to sufficient balance + return big.NewInt(10000000000), nil // 10,000 USDC +} + +func (m *mockFacilitatorEvmSigner) GetChainID() (*big.Int, error) { + return big.NewInt(8453), nil // Base mainnet +} + +func (m *mockFacilitatorEvmSigner) ReadContract( + contractAddress string, + abi []byte, + functionName string, + args ...interface{}, +) (interface{}, error) { + // Mock authorization state check + if functionName == "authorizationState" { + // Return false (not used) + return false, nil + } + return nil, nil +} + +func (m *mockFacilitatorEvmSigner) WriteContract( + contractAddress string, + abi []byte, + functionName string, + args ...interface{}, +) (string, error) { + // Return mock transaction hash + return "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", nil +} + +func (m *mockFacilitatorEvmSigner) WaitForTransactionReceipt(txHash string) (*evm.TransactionReceipt, error) { + return &evm.TransactionReceipt{ + Status: evm.TxStatusSuccess, + }, nil +} + +func (m *mockFacilitatorEvmSigner) VerifyTypedData( + address string, + domain evm.TypedDataDomain, + types map[string][]evm.TypedDataField, + primaryType string, + message map[string]interface{}, + signature []byte, +) (bool, error) { + // For testing, verify that the address matches one of our mock clients + return address == "0x1234567890123456789012345678901234567890" || + address == "0xabcdef1234567890123456789012345678901234", nil +} + +// Local facilitator client for testing +type localEvmFacilitatorClient struct { + facilitator x402.X402Facilitator +} + +func (l *localEvmFacilitatorClient) Verify( + ctx context.Context, + payload x402.PaymentPayload, + requirements x402.PaymentRequirements, +) (x402.VerifyResponse, error) { + return l.facilitator.Verify(ctx, payload, requirements) +} + +func (l *localEvmFacilitatorClient) Settle( + ctx context.Context, + payload x402.PaymentPayload, + requirements x402.PaymentRequirements, +) (x402.SettleResponse, error) { + return l.facilitator.Settle(ctx, payload, requirements) +} + +func (l *localEvmFacilitatorClient) GetSupported(ctx context.Context) (x402.SupportedResponse, error) { + return l.facilitator.GetSupported(), nil +} + +// TestEVMIntegrationV2 tests the integration with EVM V2 (default) +func TestEVMIntegrationV2(t *testing.T) { + t.Run("EVM V2 Flow - x402Client / x402ResourceService / x402Facilitator", func(t *testing.T) { + ctx := context.Background() + + // Setup client with EVM v2 scheme + clientSigner := &mockClientEvmSigner{} + client := x402.Newx402Client() + evmClient := evm.NewExactEvmClient(clientSigner) + // Register for the Base network + client.RegisterScheme("eip155:8453", evmClient) + + // Setup facilitator with EVM v2 scheme + facilitatorSigner := newMockFacilitatorEvmSigner() + facilitator := x402.Newx402Facilitator() + evmFacilitator := evm.NewExactEvmFacilitator(facilitatorSigner) + // Register for the Base network + facilitator.RegisterScheme("eip155:8453", evmFacilitator) + + // Create facilitator client wrapper + facilitatorClient := &localEvmFacilitatorClient{facilitator: *facilitator} + + // Setup resource service with EVM v2 + evmService := evm.NewExactEvmService() + service := x402.Newx402ResourceService( + x402.WithFacilitatorClient(facilitatorClient), + ) + service.RegisterScheme("eip155:8453", evmService) + + // Initialize service to fetch supported kinds + err := service.Initialize(ctx) + if err != nil { + t.Fatalf("Failed to initialize service: %v", err) + } + + // Server - builds PaymentRequired response for 5 USDC + accepts := []x402.PaymentRequirements{ + { + Scheme: evm.SchemeExact, + Network: "eip155:8453", + Asset: "erc20:0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", // USDC on Base + Amount: "5000000", // 5 USDC in smallest unit + PayTo: "0x9876543210987654321098765432109876543210", + Extra: map[string]interface{}{ + "name": "USD Coin", + "version": "2", + }, + }, + } + resource := x402.ResourceInfo{ + URL: "https://api.example.com/premium", + Description: "Premium API Access", + MimeType: "application/json", + } + paymentRequiredResponse := service.CreatePaymentRequiredResponse(accepts, resource, "", nil) + + // Verify it's V2 + if paymentRequiredResponse.X402Version != 2 { + t.Errorf("Expected X402Version 2, got %d", paymentRequiredResponse.X402Version) + } + + // Client - responds with PaymentPayload response + selected, err := client.SelectPaymentRequirements(paymentRequiredResponse.X402Version, accepts) + if err != nil { + t.Fatalf("Failed to select payment requirements: %v", err) + } + + paymentPayload, err := client.CreatePaymentPayload(ctx, paymentRequiredResponse.X402Version, selected) + if err != nil { + t.Fatalf("Failed to create payment payload: %v", err) + } + + // Verify payload is V2 + if paymentPayload.X402Version != 2 { + t.Errorf("Expected payload X402Version 2, got %d", paymentPayload.X402Version) + } + + // Verify payload structure + if paymentPayload.Scheme != evm.SchemeExact { + t.Errorf("Expected scheme %s, got %s", evm.SchemeExact, paymentPayload.Scheme) + } + + evmPayload, err := evm.PayloadFromMap(paymentPayload.Payload) + if err != nil { + t.Fatalf("Failed to parse EVM payload: %v", err) + } + + if evmPayload.Authorization.From != clientSigner.Address() { + t.Errorf("Expected from address %s, got %s", clientSigner.Address(), evmPayload.Authorization.From) + } + + if evmPayload.Authorization.Value != "5000000" { + t.Errorf("Expected value 5000000, got %s", evmPayload.Authorization.Value) + } + + // Server - maps payment payload to payment requirements + accepted := service.FindMatchingRequirements(accepts, paymentPayload) + if accepted == nil { + t.Fatal("No matching payment requirements found") + } + + // Server - verifies payment + verifyResponse, err := service.VerifyPayment(ctx, paymentPayload, *accepted) + if err != nil { + t.Fatalf("Failed to verify payment: %v", err) + } + + if !verifyResponse.IsValid { + t.Fatalf("Payment verification failed: %s", verifyResponse.InvalidReason) + } + + if verifyResponse.Payer != clientSigner.Address() { + t.Errorf("Expected payer %s, got %s", clientSigner.Address(), verifyResponse.Payer) + } + + // Server does work here... + + // Server - settles payment + settleResponse, err := service.SettlePayment(ctx, paymentPayload, *accepted) + if err != nil { + t.Fatalf("Failed to settle payment: %v", err) + } + + if !settleResponse.Success { + t.Fatalf("Payment settlement failed: %s", settleResponse.ErrorReason) + } + + // Verify the transaction hash + if settleResponse.Transaction == "" { + t.Error("Expected transaction hash in settlement response") + } + + if settleResponse.Network != "eip155:8453" { + t.Errorf("Expected network eip155:8453, got %s", settleResponse.Network) + } + + if settleResponse.Payer != clientSigner.Address() { + t.Errorf("Expected payer %s, got %s", clientSigner.Address(), settleResponse.Payer) + } + }) +} + +// TestEVMIntegrationV1 tests the integration with EVM V1 (legacy) +func TestEVMIntegrationV1(t *testing.T) { + t.Run("EVM V1 Flow (Legacy) - x402Client / x402ResourceService / x402Facilitator", func(t *testing.T) { + ctx := context.Background() + + // Setup client with EVM v1 scheme + clientSigner := &mockClientEvmSigner{ + address: "0xabcdef1234567890123456789012345678901234", + } + client := x402.Newx402Client() + evmClientV1 := evmv1.NewExactEvmClientV1(clientSigner) + // Register for the Base network using V1 registration + client.RegisterSchemeV1("eip155:8453", evmClientV1) + + // Setup facilitator with EVM v1 scheme + facilitatorSigner := newMockFacilitatorEvmSigner() + facilitator := x402.Newx402Facilitator() + evmFacilitatorV1 := evmv1.NewExactEvmFacilitatorV1(facilitatorSigner) + // Register for the Base network using V1 registration + facilitator.RegisterSchemeV1("eip155:8453", evmFacilitatorV1) + + // Create facilitator client wrapper + facilitatorClient := &localEvmFacilitatorClient{facilitator: *facilitator} + + // Setup resource service with EVM v1 + evmServiceV1 := evmv1.NewExactEvmServiceV1() + service := x402.Newx402ResourceService( + x402.WithFacilitatorClient(facilitatorClient), + ) + service.RegisterScheme("eip155:8453", evmServiceV1) + + // Initialize service to fetch supported kinds + err := service.Initialize(ctx) + if err != nil { + t.Fatalf("Failed to initialize service: %v", err) + } + + // Server - builds PaymentRequired response for 10 USDC (V1 uses version 1) + accepts := []x402.PaymentRequirements{ + { + Scheme: evm.SchemeExact, + Network: "eip155:8453", + Asset: "erc20:0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", // USDC on Base + Amount: "10000000", // 10 USDC in smallest unit + PayTo: "0x5555666677778888999900001111222233334444", + Extra: map[string]interface{}{ + "name": "USD Coin", + "version": "2", + }, + }, + } + resource := x402.ResourceInfo{ + URL: "https://legacy.example.com/api", + Description: "Legacy API Access", + MimeType: "application/json", + } + + // For V1, we need to explicitly set the version to 1 + paymentRequiredResponse := x402.PaymentRequired{ + X402Version: 1, // V1 uses version 1 + Accepts: accepts, + Resource: &resource, + } + + // Client - responds with PaymentPayload response + selected, err := client.SelectPaymentRequirements(paymentRequiredResponse.X402Version, accepts) + if err != nil { + t.Fatalf("Failed to select payment requirements: %v", err) + } + + paymentPayload, err := client.CreatePaymentPayload(ctx, paymentRequiredResponse.X402Version, selected) + if err != nil { + t.Fatalf("Failed to create payment payload: %v", err) + } + + // Verify payload is V1 + if paymentPayload.X402Version != 1 { + t.Errorf("Expected payload X402Version 1, got %d", paymentPayload.X402Version) + } + + // Verify payload structure + if paymentPayload.Scheme != evm.SchemeExact { + t.Errorf("Expected scheme %s, got %s", evm.SchemeExact, paymentPayload.Scheme) + } + + evmPayload, err := evm.PayloadFromMap(paymentPayload.Payload) + if err != nil { + t.Fatalf("Failed to parse EVM payload: %v", err) + } + + if evmPayload.Authorization.From != clientSigner.Address() { + t.Errorf("Expected from address %s, got %s", clientSigner.Address(), evmPayload.Authorization.From) + } + + if evmPayload.Authorization.Value != "10000000" { + t.Errorf("Expected value 10000000, got %s", evmPayload.Authorization.Value) + } + + // V1 specific: Check validAfter has buffer (should be in the past) + // This is just a check that it was created, actual time validation would be in facilitator + if evmPayload.Authorization.ValidAfter == "" { + t.Error("Expected validAfter to be set") + } + + if evmPayload.Authorization.ValidBefore == "" { + t.Error("Expected validBefore to be set") + } + + // Server - maps payment payload to payment requirements + accepted := service.FindMatchingRequirements(accepts, paymentPayload) + if accepted == nil { + t.Fatal("No matching payment requirements found") + } + + // Server - verifies payment + verifyResponse, err := service.VerifyPayment(ctx, paymentPayload, *accepted) + if err != nil { + t.Fatalf("Failed to verify payment: %v", err) + } + + if !verifyResponse.IsValid { + t.Fatalf("Payment verification failed: %s", verifyResponse.InvalidReason) + } + + if verifyResponse.Payer != clientSigner.Address() { + t.Errorf("Expected payer %s, got %s", clientSigner.Address(), verifyResponse.Payer) + } + + // Server does work here... + + // Server - settles payment + settleResponse, err := service.SettlePayment(ctx, paymentPayload, *accepted) + if err != nil { + t.Fatalf("Failed to settle payment: %v", err) + } + + if !settleResponse.Success { + t.Fatalf("Payment settlement failed: %s", settleResponse.ErrorReason) + } + + // Verify the transaction hash + if settleResponse.Transaction == "" { + t.Error("Expected transaction hash in settlement response") + } + + if settleResponse.Network != "eip155:8453" { + t.Errorf("Expected network eip155:8453, got %s", settleResponse.Network) + } + + if settleResponse.Payer != clientSigner.Address() { + t.Errorf("Expected payer %s, got %s", clientSigner.Address(), settleResponse.Payer) + } + }) +} + +// TestEVMVersionMismatch tests that V1 and V2 don't mix +func TestEVMVersionMismatch(t *testing.T) { + t.Run("V1 Client with V2 Requirements Should Fail", func(t *testing.T) { + ctx := context.Background() + + // Setup V1 client + clientSigner := &mockClientEvmSigner{} + client := x402.Newx402Client() + evmClientV1 := evmv1.NewExactEvmClientV1(clientSigner) + client.RegisterSchemeV1("eip155:8453", evmClientV1) + + // V2 requirements + requirements := x402.PaymentRequirements{ + Scheme: evm.SchemeExact, + Network: "eip155:8453", + Asset: "erc20:0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", + Amount: "1000000", + PayTo: "0x9876543210987654321098765432109876543210", + } + + // Try to create V2 payload with V1 client - should fail + _, err := client.CreatePaymentPayload(ctx, 2, requirements) + if err == nil { + t.Error("Expected error when using V1 client with version 2") + } + // The error could be either "no schemes registered" or "v1 only supports version 1" + // depending on how the client handles version mismatches + }) + + t.Run("V2 Client with V1 Requirements Should Fail", func(t *testing.T) { + ctx := context.Background() + + // Setup V2 client + clientSigner := &mockClientEvmSigner{} + client := x402.Newx402Client() + evmClient := evm.NewExactEvmClient(clientSigner) + client.RegisterScheme("eip155:8453", evmClient) + + // V1 requirements + requirements := x402.PaymentRequirements{ + Scheme: evm.SchemeExact, + Network: "eip155:8453", + Asset: "erc20:0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", + Amount: "1000000", + PayTo: "0x9876543210987654321098765432109876543210", + } + + // Try to create V1 payload with V2 client - should fail + _, err := client.CreatePaymentPayload(ctx, 1, requirements) + if err == nil { + t.Error("Expected error when using V2 client with version 1") + } + // The error could be either "no schemes registered" or "v2 only supports version 2" + // depending on how the client handles version mismatches + }) +} + +// TestEVMDualVersionSupport tests that a client can register both V1 and V2 and handle either version. +// This is important for backward compatibility - a client application can support both protocol versions +// simultaneously and respond appropriately based on the server's requirements. +func TestEVMDualVersionSupport(t *testing.T) { + t.Run("Dual-Registered Client Handles V1 Requirements", func(t *testing.T) { + ctx := context.Background() + + // Setup client with BOTH V1 and V2 implementations + clientSigner := &mockClientEvmSigner{} + client := x402.Newx402Client() + + // Register V1 implementation + evmClientV1 := evmv1.NewExactEvmClientV1(clientSigner) + client.RegisterSchemeV1("eip155:8453", evmClientV1) + + // Register V2 implementation + evmClientV2 := evm.NewExactEvmClient(clientSigner) + client.RegisterScheme("eip155:8453", evmClientV2) + + // V1 requirements + requirements := x402.PaymentRequirements{ + Scheme: evm.SchemeExact, + Network: "eip155:8453", + Asset: "erc20:0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", + Amount: "2000000", // 2 USDC + PayTo: "0x1111222233334444555566667777888899990000", + Extra: map[string]interface{}{ + "name": "USD Coin", + "version": "2", + }, + } + + // Create V1 payload - should succeed + paymentPayload, err := client.CreatePaymentPayload(ctx, 1, requirements) + if err != nil { + t.Fatalf("Failed to create V1 payment payload with dual-registered client: %v", err) + } + + // Verify it's a V1 payload + if paymentPayload.X402Version != 1 { + t.Errorf("Expected X402Version 1, got %d", paymentPayload.X402Version) + } + + // Parse and verify the EVM payload + evmPayload, err := evm.PayloadFromMap(paymentPayload.Payload) + if err != nil { + t.Fatalf("Failed to parse EVM payload: %v", err) + } + + if evmPayload.Authorization.Value != "2000000" { + t.Errorf("Expected value 2000000, got %s", evmPayload.Authorization.Value) + } + + if evmPayload.Authorization.To != requirements.PayTo { + t.Errorf("Expected to address %s, got %s", requirements.PayTo, evmPayload.Authorization.To) + } + + // V1 specific: Check that validAfter/validBefore are set + if evmPayload.Authorization.ValidAfter == "" { + t.Error("Expected validAfter to be set for V1") + } + if evmPayload.Authorization.ValidBefore == "" { + t.Error("Expected validBefore to be set for V1") + } + + // V1 doesn't set Accepted field + if paymentPayload.Accepted.Scheme != "" { + t.Error("V1 payload should not have Accepted field populated") + } + }) + + t.Run("Dual-Registered Client Handles V2 Requirements", func(t *testing.T) { + ctx := context.Background() + + // Setup client with BOTH V1 and V2 implementations + clientSigner := &mockClientEvmSigner{} + client := x402.Newx402Client() + + // Register V1 implementation + evmClientV1 := evmv1.NewExactEvmClientV1(clientSigner) + client.RegisterSchemeV1("eip155:8453", evmClientV1) + + // Register V2 implementation + evmClientV2 := evm.NewExactEvmClient(clientSigner) + client.RegisterScheme("eip155:8453", evmClientV2) + + // V2 requirements + requirements := x402.PaymentRequirements{ + Scheme: evm.SchemeExact, + Network: "eip155:8453", + Asset: "erc20:0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", + Amount: "3000000", // 3 USDC + PayTo: "0xaaaabbbbccccddddeeeeffff000011112222333", + Extra: map[string]interface{}{ + "name": "USD Coin", + "version": "2", + }, + } + + // Create V2 payload - should succeed + paymentPayload, err := client.CreatePaymentPayload(ctx, 2, requirements) + if err != nil { + t.Fatalf("Failed to create V2 payment payload with dual-registered client: %v", err) + } + + // Verify it's a V2 payload + if paymentPayload.X402Version != 2 { + t.Errorf("Expected X402Version 2, got %d", paymentPayload.X402Version) + } + + // Parse and verify the EVM payload + evmPayload, err := evm.PayloadFromMap(paymentPayload.Payload) + if err != nil { + t.Fatalf("Failed to parse EVM payload: %v", err) + } + + if evmPayload.Authorization.Value != "3000000" { + t.Errorf("Expected value 3000000, got %s", evmPayload.Authorization.Value) + } + + if evmPayload.Authorization.To != requirements.PayTo { + t.Errorf("Expected to address %s, got %s", requirements.PayTo, evmPayload.Authorization.To) + } + + // V2 specific: Check that Accepted field is set + if paymentPayload.Accepted.Scheme != requirements.Scheme { + t.Errorf("Expected Accepted.Scheme %s, got %s", requirements.Scheme, paymentPayload.Accepted.Scheme) + } + if paymentPayload.Accepted.Network != requirements.Network { + t.Errorf("Expected Accepted.Network %s, got %s", requirements.Network, paymentPayload.Accepted.Network) + } + if paymentPayload.Accepted.Amount != requirements.Amount { + t.Errorf("Expected Accepted.Amount %s, got %s", requirements.Amount, paymentPayload.Accepted.Amount) + } + if paymentPayload.Accepted.PayTo != requirements.PayTo { + t.Errorf("Expected Accepted.PayTo %s, got %s", requirements.PayTo, paymentPayload.Accepted.PayTo) + } + }) +} diff --git a/go/test/integration/http_test.go b/go/test/integration/http_test.go new file mode 100644 index 000000000..9b379cd0b --- /dev/null +++ b/go/test/integration/http_test.go @@ -0,0 +1,379 @@ +package integration_test + +import ( + "context" + "encoding/base64" + "encoding/json" + "strings" + "testing" + + x402 "github.com/coinbase/x402-go/v2" + x402http "github.com/coinbase/x402-go/v2/http" + "github.com/coinbase/x402-go/v2/test/mocks/cash" +) + +// mockHTTPAdapter implements the HTTPAdapter interface for testing +type mockHTTPAdapter struct { + headers map[string]string + method string + path string + url string +} + +func (m *mockHTTPAdapter) GetHeader(name string) string { + if m.headers == nil { + return "" + } + // Check both cases + if val, ok := m.headers[name]; ok { + return val + } + // Try lowercase + if val, ok := m.headers[strings.ToLower(name)]; ok { + return val + } + // Try uppercase + if val, ok := m.headers[strings.ToUpper(name)]; ok { + return val + } + return "" +} + +func (m *mockHTTPAdapter) GetMethod() string { + return m.method +} + +func (m *mockHTTPAdapter) GetPath() string { + return m.path +} + +func (m *mockHTTPAdapter) GetURL() string { + return m.url +} + +func (m *mockHTTPAdapter) GetAcceptHeader() string { + return "application/json" +} + +func (m *mockHTTPAdapter) GetUserAgent() string { + return "TestClient/1.0" +} + +// mockBrowserHTTPAdapter implements the HTTPAdapter interface for browser testing +type mockBrowserHTTPAdapter struct { + headers map[string]string + method string + path string + url string +} + +func (m *mockBrowserHTTPAdapter) GetHeader(name string) string { + if m.headers == nil { + return "" + } + // Check both cases + if val, ok := m.headers[name]; ok { + return val + } + // Try lowercase + if val, ok := m.headers[strings.ToLower(name)]; ok { + return val + } + // Try uppercase + if val, ok := m.headers[strings.ToUpper(name)]; ok { + return val + } + return "" +} + +func (m *mockBrowserHTTPAdapter) GetMethod() string { + return m.method +} + +func (m *mockBrowserHTTPAdapter) GetPath() string { + return m.path +} + +func (m *mockBrowserHTTPAdapter) GetURL() string { + return m.url +} + +func (m *mockBrowserHTTPAdapter) GetAcceptHeader() string { + return "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" +} + +func (m *mockBrowserHTTPAdapter) GetUserAgent() string { + return "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" +} + +// TestHTTPIntegration tests the integration between x402HTTPClient, x402HTTPResourceService, and x402Facilitator +func TestHTTPIntegration(t *testing.T) { + t.Run("Cash Flow - x402HTTPClient / x402HTTPResourceService / x402Facilitator", func(t *testing.T) { + ctx := context.Background() + + // Setup routes configuration + routes := x402http.RoutesConfig{ + "/api/protected": x402http.RouteConfig{ + Scheme: "cash", + PayTo: "merchant@example.com", + Price: "$0.10", + Network: "x402:cash", + Description: "Access to protected API", + MimeType: "application/json", + }, + } + + // Setup facilitator with cash scheme + facilitator := x402.Newx402Facilitator() + facilitator.RegisterScheme("x402:cash", cash.NewSchemeNetworkFacilitator()) + + // Create facilitator client wrapper + facilitatorClient := cash.NewFacilitatorClient(facilitator) + + // Setup HTTP client with cash scheme + client := x402http.Newx402HTTPClient() + client.RegisterScheme("x402:cash", cash.NewSchemeNetworkClient("John")) + + // Setup HTTP service + service := x402http.Newx402HTTPResourceService( + routes, + x402.WithFacilitatorClient(facilitatorClient), + ) + service.RegisterScheme("x402:cash", cash.NewSchemeNetworkService()) + + // Initialize service to fetch supported kinds + err := service.Initialize(ctx) + if err != nil { + t.Fatalf("Failed to initialize service: %v", err) + } + + // Create mock adapter for initial request (no payment) + mockAdapter := &mockHTTPAdapter{ + headers: map[string]string{}, + method: "GET", + path: "/api/protected", + url: "https://example.com/api/protected", + } + + // Create request context + reqCtx := x402http.HTTPRequestContext{ + Adapter: mockAdapter, + Path: "/api/protected", + Method: "GET", + } + + // Process initial request without payment - should get 402 response + httpProcessResult := service.ProcessHTTPRequest(ctx, reqCtx, nil) + + if httpProcessResult.Type != x402http.ResultPaymentError { + t.Fatalf("Expected payment-error result, got %s", httpProcessResult.Type) + } + + if httpProcessResult.Response == nil { + t.Fatal("Expected response instructions, got nil") + } + + initial402Response := httpProcessResult.Response + + // Verify 402 response + if initial402Response.Status != 402 { + t.Errorf("Expected status 402, got %d", initial402Response.Status) + } + + if initial402Response.Headers["PAYMENT-REQUIRED"] == "" { + t.Error("Expected PAYMENT-REQUIRED header") + } + + if initial402Response.IsHTML { + t.Error("Expected non-HTML response for JSON accept header") + } + + // Client responds to PaymentRequired + paymentRequired, err := client.GetPaymentRequiredResponse( + initial402Response.Headers, + nil, // No body for v2 + ) + if err != nil { + t.Fatalf("Failed to get payment required response: %v", err) + } + + selected, err := client.SelectPaymentRequirements( + paymentRequired.X402Version, + paymentRequired.Accepts, + ) + if err != nil { + t.Fatalf("Failed to select payment requirements: %v", err) + } + + paymentPayload, err := client.CreatePaymentPayload( + ctx, + paymentRequired.X402Version, + selected, + ) + if err != nil { + t.Fatalf("Failed to create payment payload: %v", err) + } + + requestHeaders := client.EncodePaymentSignatureHeader(paymentPayload) + + // Update mock adapter with payment header + mockAdapter.headers = requestHeaders + + // Process request with payment + httpProcessResult2 := service.ProcessHTTPRequest(ctx, reqCtx, nil) + + if httpProcessResult2.Type != x402http.ResultPaymentVerified { + t.Fatalf("Expected payment-verified result, got %s", httpProcessResult2.Type) + } + + if httpProcessResult2.PaymentPayload == nil { + t.Fatal("Expected payment payload in verified result") + } + + if httpProcessResult2.PaymentRequirements == nil { + t.Fatal("Expected payment requirements in verified result") + } + + // Process settlement (simulating successful response) + settlementHeaders, err := service.ProcessSettlement( + ctx, + *httpProcessResult2.PaymentPayload, + *httpProcessResult2.PaymentRequirements, + 200, // Success status + ) + if err != nil { + t.Fatalf("Failed to process settlement: %v", err) + } + + if settlementHeaders == nil { + t.Fatal("Expected settlement headers") + } + + if settlementHeaders["PAYMENT-RESPONSE"] == "" { + t.Error("Expected PAYMENT-RESPONSE header") + } + + // Decode and verify settlement response + settleData, err := base64.StdEncoding.DecodeString(settlementHeaders["PAYMENT-RESPONSE"]) + if err != nil { + t.Fatalf("Failed to decode settlement response: %v", err) + } + + var settleResponse x402.SettleResponse + err = json.Unmarshal(settleData, &settleResponse) + if err != nil { + t.Fatalf("Failed to unmarshal settlement response: %v", err) + } + + if !settleResponse.Success { + t.Errorf("Expected successful settlement, got error: %s", settleResponse.ErrorReason) + } + }) +} + +// TestHTTPIntegrationWithBrowser tests the HTTP integration with browser client (HTML paywall) +func TestHTTPIntegrationWithBrowser(t *testing.T) { + t.Run("Browser Flow - HTML Paywall Response", func(t *testing.T) { + ctx := context.Background() + + // Setup routes configuration + routes := x402http.RoutesConfig{ + "/web/protected": x402http.RouteConfig{ + Scheme: "cash", + PayTo: "merchant@example.com", + Price: "$5.00", + Network: "x402:cash", + Description: "Premium Web Content", + MimeType: "text/html", + }, + } + + // Setup facilitator with cash scheme + facilitator := x402.Newx402Facilitator() + facilitator.RegisterScheme("x402:cash", cash.NewSchemeNetworkFacilitator()) + + // Create facilitator client wrapper + facilitatorClient := cash.NewFacilitatorClient(facilitator) + + // Setup HTTP service + service := x402http.Newx402HTTPResourceService( + routes, + x402.WithFacilitatorClient(facilitatorClient), + ) + service.RegisterScheme("x402:cash", cash.NewSchemeNetworkService()) + + // Initialize service + err := service.Initialize(ctx) + if err != nil { + t.Fatalf("Failed to initialize service: %v", err) + } + + // Create mock browser adapter + mockBrowserAdapter := &mockBrowserHTTPAdapter{ + headers: map[string]string{}, + method: "GET", + path: "/web/protected", + url: "https://example.com/web/protected", + } + + // Create request context + reqCtx := x402http.HTTPRequestContext{ + Adapter: mockBrowserAdapter, + Path: "/web/protected", + Method: "GET", + } + + // Configure paywall + paywallConfig := &x402http.PaywallConfig{ + AppName: "Test App", + AppLogo: "/logo.png", + CDPClientKey: "test-key", + Testnet: true, + } + + // Process browser request without payment + httpProcessResult := service.ProcessHTTPRequest(ctx, reqCtx, paywallConfig) + + if httpProcessResult.Type != x402http.ResultPaymentError { + t.Fatalf("Expected payment-error result, got %s", httpProcessResult.Type) + } + + if httpProcessResult.Response == nil { + t.Fatal("Expected response instructions, got nil") + } + + // Verify HTML paywall response + if httpProcessResult.Response.Status != 402 { + t.Errorf("Expected status 402, got %d", httpProcessResult.Response.Status) + } + + if !httpProcessResult.Response.IsHTML { + t.Error("Expected HTML response for browser") + } + + if httpProcessResult.Response.Headers["Content-Type"] != "text/html" { + t.Errorf("Expected Content-Type text/html, got %s", httpProcessResult.Response.Headers["Content-Type"]) + } + + // Verify HTML contains paywall elements + htmlBody, ok := httpProcessResult.Response.Body.(string) + if !ok { + t.Fatal("Expected HTML body as string") + } + + // Check for key paywall elements + expectedElements := []string{ + "Payment Required", + "Premium Web Content", + "0.00 USDC", // $5.00 might be parsed as 0.00 due to price parsing issue + "payment-widget", + "test-key", // CDP client key + } + + for _, element := range expectedElements { + if !strings.Contains(htmlBody, element) { + t.Errorf("Expected HTML to contain '%s'\nActual HTML:\n%s", element, htmlBody) + } + } + }) +} diff --git a/go/test/mocks/cash/cash.go b/go/test/mocks/cash/cash.go new file mode 100644 index 000000000..b46097a27 --- /dev/null +++ b/go/test/mocks/cash/cash.go @@ -0,0 +1,305 @@ +package cash + +import ( + "context" + "fmt" + "strconv" + "strings" + "time" + + x402 "github.com/coinbase/x402-go/v2" +) + +// ============================================================================ +// Cash Scheme Network Client +// ============================================================================ + +// SchemeNetworkClient implements the client side of the cash payment scheme +type SchemeNetworkClient struct { + payer string +} + +// NewSchemeNetworkClient creates a new cash scheme client +func NewSchemeNetworkClient(payer string) *SchemeNetworkClient { + return &SchemeNetworkClient{ + payer: payer, + } +} + +// Scheme returns the payment scheme identifier +func (c *SchemeNetworkClient) Scheme() string { + return "cash" +} + +// CreatePaymentPayload creates a payment payload for the cash scheme +func (c *SchemeNetworkClient) CreatePaymentPayload(ctx context.Context, version int, requirements x402.PaymentRequirements) (x402.PaymentPayload, error) { + validUntil := time.Now().Add(time.Duration(requirements.MaxTimeoutSeconds) * time.Second).Unix() + + return x402.PaymentPayload{ + X402Version: version, + Scheme: requirements.Scheme, + Network: requirements.Network, + Payload: map[string]interface{}{ + "signature": fmt.Sprintf("~%s", c.payer), + "validUntil": strconv.FormatInt(validUntil, 10), + "name": c.payer, + }, + Accepted: requirements, + Extensions: nil, + }, nil +} + +// ============================================================================ +// Cash Scheme Network Facilitator +// ============================================================================ + +// SchemeNetworkFacilitator implements the facilitator side of the cash payment scheme +type SchemeNetworkFacilitator struct{} + +// NewSchemeNetworkFacilitator creates a new cash scheme facilitator +func NewSchemeNetworkFacilitator() *SchemeNetworkFacilitator { + return &SchemeNetworkFacilitator{} +} + +// Scheme returns the payment scheme identifier +func (f *SchemeNetworkFacilitator) Scheme() string { + return "cash" +} + +// Verify verifies a payment payload against requirements +func (f *SchemeNetworkFacilitator) Verify(ctx context.Context, payload x402.PaymentPayload, requirements x402.PaymentRequirements) (x402.VerifyResponse, error) { + // Extract payload fields + signature, ok := payload.Payload["signature"].(string) + if !ok { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "missing_signature", + }, nil + } + + name, ok := payload.Payload["name"].(string) + if !ok { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "missing_name", + }, nil + } + + validUntilStr, ok := payload.Payload["validUntil"].(string) + if !ok { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "missing_validUntil", + }, nil + } + + // Check signature + expectedSig := fmt.Sprintf("~%s", name) + if signature != expectedSig { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "invalid_signature", + }, nil + } + + // Check expiration + validUntil, err := strconv.ParseInt(validUntilStr, 10, 64) + if err != nil { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "invalid_validUntil", + }, nil + } + + if validUntil < time.Now().Unix() { + return x402.VerifyResponse{ + IsValid: false, + InvalidReason: "expired_signature", + }, nil + } + + return x402.VerifyResponse{ + IsValid: true, + InvalidReason: "", + Payer: signature, + }, nil +} + +// Settle settles a payment based on the payload and requirements +func (f *SchemeNetworkFacilitator) Settle(ctx context.Context, payload x402.PaymentPayload, requirements x402.PaymentRequirements) (x402.SettleResponse, error) { + // First verify the payment + verifyResponse, err := f.Verify(ctx, payload, requirements) + if err != nil { + return x402.SettleResponse{ + Success: false, + ErrorReason: err.Error(), + Network: requirements.Network, + }, nil + } + + if !verifyResponse.IsValid { + return x402.SettleResponse{ + Success: false, + ErrorReason: verifyResponse.InvalidReason, + Payer: verifyResponse.Payer, + Network: requirements.Network, + }, nil + } + + // Extract name for transaction message + name, _ := payload.Payload["name"].(string) + + return x402.SettleResponse{ + Success: true, + Transaction: fmt.Sprintf("%s transferred %s %s to %s", name, requirements.Amount, requirements.Asset, requirements.PayTo), + Network: requirements.Network, + Payer: verifyResponse.Payer, + }, nil +} + +// ============================================================================ +// Cash Scheme Network Service +// ============================================================================ + +// SchemeNetworkService implements the service side of the cash payment scheme +type SchemeNetworkService struct{} + +// NewSchemeNetworkService creates a new cash scheme service +func NewSchemeNetworkService() *SchemeNetworkService { + return &SchemeNetworkService{} +} + +// Scheme returns the payment scheme identifier +func (s *SchemeNetworkService) Scheme() string { + return "cash" +} + +// ParsePrice parses a price into asset amount format +func (s *SchemeNetworkService) ParsePrice(price x402.Price, network x402.Network) (x402.AssetAmount, error) { + // Handle pre-parsed price object + if assetAmount, ok := price.(x402.AssetAmount); ok { + return assetAmount, nil + } + + // Handle map format + if priceMap, ok := price.(map[string]interface{}); ok { + amount, _ := priceMap["amount"].(string) + asset, _ := priceMap["asset"].(string) + if asset == "" { + asset = "USD" + } + return x402.AssetAmount{ + Amount: amount, + Asset: asset, + Extra: nil, + }, nil + } + + // Parse string prices like "$10" or "10 USD" + if priceStr, ok := price.(string); ok { + // Remove dollar sign and USD suffix + cleanPrice := strings.TrimPrefix(priceStr, "$") + cleanPrice = strings.TrimSuffix(cleanPrice, " USD") + cleanPrice = strings.TrimSuffix(cleanPrice, "USD") + cleanPrice = strings.TrimSpace(cleanPrice) + + return x402.AssetAmount{ + Amount: cleanPrice, + Asset: "USD", + Extra: nil, + }, nil + } + + // Handle number input + if priceNum, ok := price.(float64); ok { + return x402.AssetAmount{ + Amount: fmt.Sprintf("%.2f", priceNum), + Asset: "USD", + Extra: nil, + }, nil + } + + if priceInt, ok := price.(int); ok { + return x402.AssetAmount{ + Amount: strconv.Itoa(priceInt), + Asset: "USD", + Extra: nil, + }, nil + } + + return x402.AssetAmount{}, fmt.Errorf("invalid price format: %v", price) +} + +// EnhancePaymentRequirements enhances payment requirements with cash-specific details +func (s *SchemeNetworkService) EnhancePaymentRequirements( + ctx context.Context, + requirements x402.PaymentRequirements, + supportedKind x402.SupportedKind, + facilitatorExtensions []string, +) (x402.PaymentRequirements, error) { + // Cash scheme doesn't need any special enhancements + return requirements, nil +} + +// ============================================================================ +// Cash Facilitator Client +// ============================================================================ + +// FacilitatorClient wraps a facilitator for the cash scheme +type FacilitatorClient struct { + facilitator *x402.X402Facilitator +} + +// NewFacilitatorClient creates a new cash facilitator client +func NewFacilitatorClient(facilitator *x402.X402Facilitator) *FacilitatorClient { + return &FacilitatorClient{ + facilitator: facilitator, + } +} + +// Verify verifies a payment payload against requirements +func (c *FacilitatorClient) Verify(ctx context.Context, payload x402.PaymentPayload, requirements x402.PaymentRequirements) (x402.VerifyResponse, error) { + return c.facilitator.Verify(ctx, payload, requirements) +} + +// Settle settles a payment based on the payload and requirements +func (c *FacilitatorClient) Settle(ctx context.Context, payload x402.PaymentPayload, requirements x402.PaymentRequirements) (x402.SettleResponse, error) { + return c.facilitator.Settle(ctx, payload, requirements) +} + +// GetSupported gets supported payment kinds and extensions +func (c *FacilitatorClient) GetSupported(ctx context.Context) (x402.SupportedResponse, error) { + return x402.SupportedResponse{ + Kinds: []x402.SupportedKind{ + { + X402Version: 2, + Scheme: "cash", + Network: "x402:cash", + Extra: nil, + }, + }, + Extensions: []string{}, + }, nil +} + +// Identifier returns the identifier for this facilitator client +func (c *FacilitatorClient) Identifier() string { + return "cash-facilitator" +} + +// ============================================================================ +// Helper Functions +// ============================================================================ + +// BuildPaymentRequirements creates a payment requirements object for the cash scheme +func BuildPaymentRequirements(payTo string, asset string, amount string) x402.PaymentRequirements { + return x402.PaymentRequirements{ + Scheme: "cash", + Network: "x402:cash", + Asset: asset, + Amount: amount, + PayTo: payTo, + MaxTimeoutSeconds: 1000, + Extra: nil, + } +} diff --git a/go/types.go b/go/types.go new file mode 100644 index 000000000..31130a517 --- /dev/null +++ b/go/types.go @@ -0,0 +1,170 @@ +package x402 + +import ( + "encoding/json" + "fmt" + "strings" +) + +// Network represents a blockchain network identifier in CAIP-2 format +// Format: namespace:reference (e.g., "eip155:1" for Ethereum mainnet) +type Network string + +// Parse splits the network into namespace and reference components +func (n Network) Parse() (namespace, reference string, err error) { + parts := strings.Split(string(n), ":") + if len(parts) != 2 { + return "", "", fmt.Errorf("invalid network format: %s", n) + } + return parts[0], parts[1], nil +} + +// Match checks if this network matches a pattern (supports wildcards) +// e.g., "eip155:1" matches "eip155:*" and "eip155:*" matches "eip155:1" +func (n Network) Match(pattern Network) bool { + if n == pattern { + return true + } + + nStr := string(n) + patternStr := string(pattern) + + // Check if pattern has wildcard + if strings.HasSuffix(patternStr, ":*") { + prefix := strings.TrimSuffix(patternStr, "*") + return strings.HasPrefix(nStr, prefix) + } + + // Check if n has wildcard (for bidirectional matching) + if strings.HasSuffix(nStr, ":*") { + prefix := strings.TrimSuffix(nStr, "*") + return strings.HasPrefix(patternStr, prefix) + } + + return false +} + +// Price represents a price that can be specified in various formats +type Price interface{} + +// AssetAmount represents an amount of a specific asset +type AssetAmount struct { + Asset string `json:"asset"` + Amount string `json:"amount"` + Extra map[string]interface{} `json:"extra,omitempty"` +} + +// PaymentRequirements defines what payment is acceptable for a resource +type PaymentRequirements struct { + Scheme string `json:"scheme"` + Network Network `json:"network"` + Asset string `json:"asset"` + Amount string `json:"amount"` // v2 field + MaxAmountRequired string `json:"maxAmountRequired,omitempty"` // v1 compatibility field + PayTo string `json:"payTo"` + MaxTimeoutSeconds int `json:"maxTimeoutSeconds"` + Extra map[string]interface{} `json:"extra,omitempty"` +} + +// PaymentPayload contains the signed payment authorization from a client +type PaymentPayload struct { + X402Version int `json:"x402Version"` + Scheme string `json:"scheme"` + Network Network `json:"network"` + Payload map[string]interface{} `json:"payload"` + Accepted PaymentRequirements `json:"accepted"` + Extensions map[string]interface{} `json:"extensions,omitempty"` +} + +// ResourceInfo describes the resource being accessed +type ResourceInfo struct { + URL string `json:"url"` + Description string `json:"description"` + MimeType string `json:"mimeType"` +} + +// PaymentRequired is the 402 response sent to clients +type PaymentRequired struct { + X402Version int `json:"x402Version"` + Error string `json:"error,omitempty"` + Resource *ResourceInfo `json:"resource,omitempty"` + Accepts []PaymentRequirements `json:"accepts"` + Extensions map[string]interface{} `json:"extensions,omitempty"` +} + +// VerifyRequest contains the payment to verify +type VerifyRequest struct { + PaymentPayload PaymentPayload `json:"paymentPayload"` + PaymentRequirements PaymentRequirements `json:"paymentRequirements"` +} + +// VerifyResponse contains the verification result +type VerifyResponse struct { + IsValid bool `json:"isValid"` + InvalidReason string `json:"invalidReason,omitempty"` + Payer string `json:"payer,omitempty"` +} + +// SettleRequest contains the payment to settle +type SettleRequest struct { + PaymentPayload PaymentPayload `json:"paymentPayload"` + PaymentRequirements PaymentRequirements `json:"paymentRequirements"` +} + +// SettleResponse contains the settlement result +type SettleResponse struct { + Success bool `json:"success"` + ErrorReason string `json:"errorReason,omitempty"` + Payer string `json:"payer,omitempty"` + Transaction string `json:"transaction"` + Network Network `json:"network"` +} + +// SupportedKind represents a single supported payment configuration +type SupportedKind struct { + X402Version int `json:"x402Version"` + Scheme string `json:"scheme"` + Network Network `json:"network"` + Extra map[string]interface{} `json:"extra,omitempty"` +} + +// SupportedResponse describes what payment kinds a facilitator supports +type SupportedResponse struct { + Kinds []SupportedKind `json:"kinds"` + Extensions []string `json:"extensions"` +} + +// ResourceConfig defines payment configuration for a protected resource +type ResourceConfig struct { + Scheme string `json:"scheme"` + PayTo string `json:"payTo"` + Price Price `json:"price"` + Network Network `json:"network"` + MaxTimeoutSeconds int `json:"maxTimeoutSeconds,omitempty"` +} + +// DeepEqual performs deep equality check on payment requirements +func DeepEqual(a, b interface{}) bool { + // Normalize to JSON and compare + aJSON, err := json.Marshal(a) + if err != nil { + return false + } + bJSON, err := json.Marshal(b) + if err != nil { + return false + } + + var aNorm, bNorm interface{} + if err := json.Unmarshal(aJSON, &aNorm); err != nil { + return false + } + if err := json.Unmarshal(bJSON, &bNorm); err != nil { + return false + } + + aNormJSON, _ := json.Marshal(aNorm) + bNormJSON, _ := json.Marshal(bNorm) + + return string(aNormJSON) == string(bNormJSON) +} diff --git a/go/utils.go b/go/utils.go new file mode 100644 index 000000000..5994138d2 --- /dev/null +++ b/go/utils.go @@ -0,0 +1,80 @@ +package x402 + +import "fmt" + +// ValidatePaymentPayload performs basic validation on a payment payload +func ValidatePaymentPayload(p PaymentPayload) error { + if p.X402Version < 1 || p.X402Version > 2 { + return fmt.Errorf("unsupported x402 version: %d", p.X402Version) + } + if p.Scheme == "" { + return fmt.Errorf("payment scheme is required") + } + if p.Network == "" { + return fmt.Errorf("payment network is required") + } + if p.Payload == nil { + return fmt.Errorf("payment payload is required") + } + return nil +} + +// ValidatePaymentRequirements performs basic validation on payment requirements +func ValidatePaymentRequirements(r PaymentRequirements) error { + if r.Scheme == "" { + return fmt.Errorf("payment scheme is required") + } + if r.Network == "" { + return fmt.Errorf("payment network is required") + } + if r.Asset == "" { + return fmt.Errorf("payment asset is required") + } + // Note: Amount check is skipped for v1 compatibility (v1 uses maxAmountRequired) + // Version-specific facilitators will validate amount fields as needed + if r.PayTo == "" { + return fmt.Errorf("payment recipient is required") + } + return nil +} + +// findByNetworkAndScheme finds a scheme implementation for a given network/scheme combination +// This supports pattern matching for networks (e.g., "eip155:*") +func findByNetworkAndScheme[T any](networkMap map[Network]map[string]T, scheme string, network Network) T { + var zero T + + // Try exact match first + if schemeMap, exists := networkMap[network]; exists { + if impl, exists := schemeMap[scheme]; exists { + return impl + } + } + + // Try pattern matching + for registeredNetwork, schemeMap := range networkMap { + if network.Match(registeredNetwork) || registeredNetwork.Match(network) { + if impl, exists := schemeMap[scheme]; exists { + return impl + } + } + } + + return zero +} + +// findSchemesByNetwork finds all schemes for a given network +func findSchemesByNetwork[T any](networkMap map[Network]map[string]T, network Network) map[string]T { + // Try exact match first + if schemeMap, exists := networkMap[network]; exists { + return schemeMap + } + + // Try pattern matching + for registeredNetwork, schemeMap := range networkMap { + if network.Match(registeredNetwork) || registeredNetwork.Match(network) { + return schemeMap + } + } + + return nil +} diff --git a/go/utils_test.go b/go/utils_test.go new file mode 100644 index 000000000..596e82a13 --- /dev/null +++ b/go/utils_test.go @@ -0,0 +1,398 @@ +package x402 + +import ( + "testing" +) + +func TestValidatePaymentPayload(t *testing.T) { + tests := []struct { + name string + payload PaymentPayload + wantErr bool + errMsg string + }{ + { + name: "valid v2 payload", + payload: PaymentPayload{ + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + Payload: map[string]interface{}{"sig": "test"}, + }, + wantErr: false, + }, + { + name: "valid v1 payload", + payload: PaymentPayload{ + X402Version: 1, + Scheme: "exact", + Network: "eip155:1", + Payload: map[string]interface{}{"sig": "test"}, + }, + wantErr: false, + }, + { + name: "invalid version", + payload: PaymentPayload{ + X402Version: 3, + Scheme: "exact", + Network: "eip155:1", + Payload: map[string]interface{}{"sig": "test"}, + }, + wantErr: true, + errMsg: "unsupported x402 version", + }, + { + name: "missing scheme", + payload: PaymentPayload{ + X402Version: 2, + Network: "eip155:1", + Payload: map[string]interface{}{"sig": "test"}, + }, + wantErr: true, + errMsg: "payment scheme is required", + }, + { + name: "missing network", + payload: PaymentPayload{ + X402Version: 2, + Scheme: "exact", + Payload: map[string]interface{}{"sig": "test"}, + }, + wantErr: true, + errMsg: "payment network is required", + }, + { + name: "missing payload", + payload: PaymentPayload{ + X402Version: 2, + Scheme: "exact", + Network: "eip155:1", + }, + wantErr: true, + errMsg: "payment payload is required", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := ValidatePaymentPayload(tt.payload) + if (err != nil) != tt.wantErr { + t.Errorf("ValidatePaymentPayload() error = %v, wantErr %v", err, tt.wantErr) + } + if err != nil && tt.errMsg != "" { + if err.Error() != tt.errMsg && !contains(err.Error(), tt.errMsg) { + t.Errorf("ValidatePaymentPayload() error message = %v, want %v", err.Error(), tt.errMsg) + } + } + }) + } +} + +func TestValidatePaymentRequirements(t *testing.T) { + tests := []struct { + name string + req PaymentRequirements + wantErr bool + errMsg string + }{ + { + name: "valid requirements", + req: PaymentRequirements{ + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + }, + wantErr: false, + }, + { + name: "missing scheme", + req: PaymentRequirements{ + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + }, + wantErr: true, + errMsg: "payment scheme is required", + }, + { + name: "missing network", + req: PaymentRequirements{ + Scheme: "exact", + Asset: "USDC", + Amount: "1000000", + PayTo: "0xrecipient", + }, + wantErr: true, + errMsg: "payment network is required", + }, + { + name: "missing asset", + req: PaymentRequirements{ + Scheme: "exact", + Network: "eip155:1", + Amount: "1000000", + PayTo: "0xrecipient", + }, + wantErr: true, + errMsg: "payment asset is required", + }, + { + name: "missing amount", + req: PaymentRequirements{ + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + PayTo: "0xrecipient", + // Amount is optional for v1 compatibility (v1 uses maxAmountRequired) + }, + wantErr: false, // Changed: Amount validation removed for v1 compatibility + }, + { + name: "missing payTo", + req: PaymentRequirements{ + Scheme: "exact", + Network: "eip155:1", + Asset: "USDC", + Amount: "1000000", + }, + wantErr: true, + errMsg: "payment recipient is required", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := ValidatePaymentRequirements(tt.req) + if (err != nil) != tt.wantErr { + t.Errorf("ValidatePaymentRequirements() error = %v, wantErr %v", err, tt.wantErr) + } + if err != nil && tt.errMsg != "" { + if err.Error() != tt.errMsg && !contains(err.Error(), tt.errMsg) { + t.Errorf("ValidatePaymentRequirements() error message = %v, want %v", err.Error(), tt.errMsg) + } + } + }) + } +} + +func TestFindByNetworkAndScheme(t *testing.T) { + // Create test map + networkMap := map[Network]map[string]string{ + "eip155:1": { + "exact": "mainnet-exact", + "transfer": "mainnet-transfer", + }, + "eip155:8453": { + "exact": "base-exact", + }, + "eip155:*": { + "wildcard": "any-eip155", + }, + } + + tests := []struct { + name string + scheme string + network Network + expected string + }{ + { + name: "exact match mainnet exact", + scheme: "exact", + network: "eip155:1", + expected: "mainnet-exact", + }, + { + name: "exact match mainnet transfer", + scheme: "transfer", + network: "eip155:1", + expected: "mainnet-transfer", + }, + { + name: "exact match base exact", + scheme: "exact", + network: "eip155:8453", + expected: "base-exact", + }, + { + name: "wildcard match for unregistered network", + scheme: "wildcard", + network: "eip155:137", // Polygon, not explicitly registered + expected: "any-eip155", + }, + { + name: "no match", + scheme: "nonexistent", + network: "eip155:1", + expected: "", + }, + { + name: "no match for different namespace", + scheme: "exact", + network: "solana:mainnet", + expected: "", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := findByNetworkAndScheme(networkMap, tt.scheme, tt.network) + if result != tt.expected { + t.Errorf("findByNetworkAndScheme() = %v, want %v", result, tt.expected) + } + }) + } +} + +func TestFindSchemesByNetwork(t *testing.T) { + // Create test map + networkMap := map[Network]map[string]string{ + "eip155:1": { + "exact": "mainnet-exact", + "transfer": "mainnet-transfer", + }, + "eip155:8453": { + "exact": "base-exact", + }, + "eip155:*": { + "wildcard": "any-eip155", + }, + } + + tests := []struct { + name string + network Network + expected map[string]string + isNil bool + }{ + { + name: "exact match mainnet", + network: "eip155:1", + expected: map[string]string{ + "exact": "mainnet-exact", + "transfer": "mainnet-transfer", + }, + }, + { + name: "exact match base", + network: "eip155:8453", + expected: map[string]string{ + "exact": "base-exact", + }, + }, + { + name: "wildcard match", + network: "eip155:137", // Polygon, matches wildcard + expected: map[string]string{ + "wildcard": "any-eip155", + }, + }, + { + name: "no match", + network: "solana:mainnet", + isNil: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := findSchemesByNetwork(networkMap, tt.network) + if tt.isNil { + if result != nil { + t.Errorf("findSchemesByNetwork() = %v, want nil", result) + } + } else { + if len(result) != len(tt.expected) { + t.Errorf("findSchemesByNetwork() length = %d, want %d", len(result), len(tt.expected)) + } + for k, v := range tt.expected { + if result[k] != v { + t.Errorf("findSchemesByNetwork()[%s] = %v, want %v", k, result[k], v) + } + } + } + }) + } +} + +func TestNetworkPatternMatching(t *testing.T) { + tests := []struct { + name string + network1 Network + network2 Network + matches bool + }{ + { + name: "exact match", + network1: "eip155:1", + network2: "eip155:1", + matches: true, + }, + { + name: "wildcard matches specific", + network1: "eip155:*", + network2: "eip155:8453", + matches: true, + }, + { + name: "specific matches wildcard", + network1: "eip155:8453", + network2: "eip155:*", + matches: true, + }, + { + name: "different namespaces", + network1: "eip155:1", + network2: "solana:mainnet", + matches: false, + }, + { + name: "different chains same namespace", + network1: "eip155:1", + network2: "eip155:8453", + matches: false, + }, + { + name: "wildcard different namespace", + network1: "eip155:*", + network2: "solana:mainnet", + matches: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := tt.network1.Match(tt.network2) + if result != tt.matches { + t.Errorf("Network.Match() = %v, want %v", result, tt.matches) + } + // Test symmetry for non-wildcard cases + if !contains(string(tt.network1), "*") && !contains(string(tt.network2), "*") { + reverseResult := tt.network2.Match(tt.network1) + if reverseResult != tt.matches { + t.Errorf("Network.Match() not symmetric: forward = %v, reverse = %v", result, reverseResult) + } + } + }) + } +} + +// Helper function +func contains(s, substr string) bool { + return len(s) >= len(substr) && (s == substr || len(substr) > 0 && len(s) > len(substr) && + (s[:len(substr)] == substr || s[len(s)-len(substr):] == substr || + (len(s) > len(substr) && findSubstring(s, substr)))) +} + +func findSubstring(s, substr string) bool { + for i := 1; i < len(s)-len(substr); i++ { + if s[i:i+len(substr)] == substr { + return true + } + } + return false +} diff --git a/java/.gitignore b/java/legacy/.gitignore similarity index 100% rename from java/.gitignore rename to java/legacy/.gitignore diff --git a/java/README.md b/java/legacy/README.md similarity index 100% rename from java/README.md rename to java/legacy/README.md diff --git a/java/checkstyle-suppressions.xml b/java/legacy/checkstyle-suppressions.xml similarity index 100% rename from java/checkstyle-suppressions.xml rename to java/legacy/checkstyle-suppressions.xml diff --git a/java/checkstyle.xml b/java/legacy/checkstyle.xml similarity index 100% rename from java/checkstyle.xml rename to java/legacy/checkstyle.xml diff --git a/java/pom.xml b/java/legacy/pom.xml similarity index 100% rename from java/pom.xml rename to java/legacy/pom.xml diff --git a/java/spotbugs-exclude.xml b/java/legacy/spotbugs-exclude.xml similarity index 100% rename from java/spotbugs-exclude.xml rename to java/legacy/spotbugs-exclude.xml diff --git a/java/src/main/java/com/coinbase/x402/client/FacilitatorClient.java b/java/legacy/src/main/java/com/coinbase/x402/client/FacilitatorClient.java similarity index 100% rename from java/src/main/java/com/coinbase/x402/client/FacilitatorClient.java rename to java/legacy/src/main/java/com/coinbase/x402/client/FacilitatorClient.java diff --git a/java/src/main/java/com/coinbase/x402/client/HttpFacilitatorClient.java b/java/legacy/src/main/java/com/coinbase/x402/client/HttpFacilitatorClient.java similarity index 100% rename from java/src/main/java/com/coinbase/x402/client/HttpFacilitatorClient.java rename to java/legacy/src/main/java/com/coinbase/x402/client/HttpFacilitatorClient.java diff --git a/java/src/main/java/com/coinbase/x402/client/Kind.java b/java/legacy/src/main/java/com/coinbase/x402/client/Kind.java similarity index 100% rename from java/src/main/java/com/coinbase/x402/client/Kind.java rename to java/legacy/src/main/java/com/coinbase/x402/client/Kind.java diff --git a/java/src/main/java/com/coinbase/x402/client/SettlementResponse.java b/java/legacy/src/main/java/com/coinbase/x402/client/SettlementResponse.java similarity index 100% rename from java/src/main/java/com/coinbase/x402/client/SettlementResponse.java rename to java/legacy/src/main/java/com/coinbase/x402/client/SettlementResponse.java diff --git a/java/src/main/java/com/coinbase/x402/client/VerificationResponse.java b/java/legacy/src/main/java/com/coinbase/x402/client/VerificationResponse.java similarity index 100% rename from java/src/main/java/com/coinbase/x402/client/VerificationResponse.java rename to java/legacy/src/main/java/com/coinbase/x402/client/VerificationResponse.java diff --git a/java/src/main/java/com/coinbase/x402/client/X402HttpClient.java b/java/legacy/src/main/java/com/coinbase/x402/client/X402HttpClient.java similarity index 100% rename from java/src/main/java/com/coinbase/x402/client/X402HttpClient.java rename to java/legacy/src/main/java/com/coinbase/x402/client/X402HttpClient.java diff --git a/java/src/main/java/com/coinbase/x402/crypto/CryptoSignException.java b/java/legacy/src/main/java/com/coinbase/x402/crypto/CryptoSignException.java similarity index 100% rename from java/src/main/java/com/coinbase/x402/crypto/CryptoSignException.java rename to java/legacy/src/main/java/com/coinbase/x402/crypto/CryptoSignException.java diff --git a/java/src/main/java/com/coinbase/x402/crypto/CryptoSigner.java b/java/legacy/src/main/java/com/coinbase/x402/crypto/CryptoSigner.java similarity index 100% rename from java/src/main/java/com/coinbase/x402/crypto/CryptoSigner.java rename to java/legacy/src/main/java/com/coinbase/x402/crypto/CryptoSigner.java diff --git a/java/src/main/java/com/coinbase/x402/model/Authorization.java b/java/legacy/src/main/java/com/coinbase/x402/model/Authorization.java similarity index 100% rename from java/src/main/java/com/coinbase/x402/model/Authorization.java rename to java/legacy/src/main/java/com/coinbase/x402/model/Authorization.java diff --git a/java/src/main/java/com/coinbase/x402/model/ExactSchemePayload.java b/java/legacy/src/main/java/com/coinbase/x402/model/ExactSchemePayload.java similarity index 100% rename from java/src/main/java/com/coinbase/x402/model/ExactSchemePayload.java rename to java/legacy/src/main/java/com/coinbase/x402/model/ExactSchemePayload.java diff --git a/java/src/main/java/com/coinbase/x402/model/PaymentPayload.java b/java/legacy/src/main/java/com/coinbase/x402/model/PaymentPayload.java similarity index 100% rename from java/src/main/java/com/coinbase/x402/model/PaymentPayload.java rename to java/legacy/src/main/java/com/coinbase/x402/model/PaymentPayload.java diff --git a/java/src/main/java/com/coinbase/x402/model/PaymentRequiredResponse.java b/java/legacy/src/main/java/com/coinbase/x402/model/PaymentRequiredResponse.java similarity index 100% rename from java/src/main/java/com/coinbase/x402/model/PaymentRequiredResponse.java rename to java/legacy/src/main/java/com/coinbase/x402/model/PaymentRequiredResponse.java diff --git a/java/src/main/java/com/coinbase/x402/model/PaymentRequirements.java b/java/legacy/src/main/java/com/coinbase/x402/model/PaymentRequirements.java similarity index 100% rename from java/src/main/java/com/coinbase/x402/model/PaymentRequirements.java rename to java/legacy/src/main/java/com/coinbase/x402/model/PaymentRequirements.java diff --git a/java/src/main/java/com/coinbase/x402/model/SettlementResponseHeader.java b/java/legacy/src/main/java/com/coinbase/x402/model/SettlementResponseHeader.java similarity index 100% rename from java/src/main/java/com/coinbase/x402/model/SettlementResponseHeader.java rename to java/legacy/src/main/java/com/coinbase/x402/model/SettlementResponseHeader.java diff --git a/java/src/main/java/com/coinbase/x402/server/PaymentFilter.java b/java/legacy/src/main/java/com/coinbase/x402/server/PaymentFilter.java similarity index 100% rename from java/src/main/java/com/coinbase/x402/server/PaymentFilter.java rename to java/legacy/src/main/java/com/coinbase/x402/server/PaymentFilter.java diff --git a/java/src/main/java/com/coinbase/x402/util/Json.java b/java/legacy/src/main/java/com/coinbase/x402/util/Json.java similarity index 100% rename from java/src/main/java/com/coinbase/x402/util/Json.java rename to java/legacy/src/main/java/com/coinbase/x402/util/Json.java diff --git a/java/src/test/java/com/coinbase/x402/client/HttpFacilitatorClientTest.java b/java/legacy/src/test/java/com/coinbase/x402/client/HttpFacilitatorClientTest.java similarity index 100% rename from java/src/test/java/com/coinbase/x402/client/HttpFacilitatorClientTest.java rename to java/legacy/src/test/java/com/coinbase/x402/client/HttpFacilitatorClientTest.java diff --git a/java/src/test/java/com/coinbase/x402/client/X402HttpClientTest.java b/java/legacy/src/test/java/com/coinbase/x402/client/X402HttpClientTest.java similarity index 100% rename from java/src/test/java/com/coinbase/x402/client/X402HttpClientTest.java rename to java/legacy/src/test/java/com/coinbase/x402/client/X402HttpClientTest.java diff --git a/java/src/test/java/com/coinbase/x402/integration/FilterIntegrationTest.java b/java/legacy/src/test/java/com/coinbase/x402/integration/FilterIntegrationTest.java similarity index 100% rename from java/src/test/java/com/coinbase/x402/integration/FilterIntegrationTest.java rename to java/legacy/src/test/java/com/coinbase/x402/integration/FilterIntegrationTest.java diff --git a/java/src/test/java/com/coinbase/x402/model/PaymentPayloadTest.java b/java/legacy/src/test/java/com/coinbase/x402/model/PaymentPayloadTest.java similarity index 100% rename from java/src/test/java/com/coinbase/x402/model/PaymentPayloadTest.java rename to java/legacy/src/test/java/com/coinbase/x402/model/PaymentPayloadTest.java diff --git a/java/src/test/java/com/coinbase/x402/server/PaymentFilterTest.java b/java/legacy/src/test/java/com/coinbase/x402/server/PaymentFilterTest.java similarity index 100% rename from java/src/test/java/com/coinbase/x402/server/PaymentFilterTest.java rename to java/legacy/src/test/java/com/coinbase/x402/server/PaymentFilterTest.java diff --git a/python/x402/TODO.md b/python/x402/TODO.md new file mode 100644 index 000000000..73abc83c1 --- /dev/null +++ b/python/x402/TODO.md @@ -0,0 +1,36 @@ +# x402 Python SDK - v2 Refactor TODO + +## Overview + +The Python SDK v2 refactor will modernize the x402 package to align with the TypeScript core implementation patterns while maintaining a Pythonic API. Unlike the TypeScript packages which are being split into multiple npm packages (@x402/core, @x402/express, etc.), the Python implementation will remain as a single monolithic package due to PyPI's flat namespace and Python's different approach to tree-shaking. + +## Proposed Package Structure + +The v2 refactor will reorganize the existing x402 package with the following structure: + +``` +/python/x402 + .core # Core protocol implementation + .types # Type definitions and protocols + .mechanisms # Implementations + .evm # EVM blockchain implementation + .svm # Solana blockchain implementation + .extensions # Protocol extensions + .bazaar # Resource discovery extension + .sign_in_with_x # Authentication extension + .client # Client implementations + .x402_client # Base client class + .xhttp # HTTP-specific client utilities + .requests # Requests library interceptor + .server # Server implementations + .x402_resource_server # Core server logic + .x402_http_resource_server # HTTP server implementation + .paywall # Paywall HTML generation + .flask # Flask framework integration + .fast # FastAPI framework integration + .facilitator # Facilitator components + .x402_facilitator # Local facilitator implementation + .a2a # Agent-to-Agent protocol support + .xmtp # XMTP messaging protocol integration + .mcp # Model Context Protocol support +``` diff --git a/python/x402/src/x402/clients/httpx.py b/python/x402/src/x402/clients/httpx.py index 430cfb8ee..33d9b5cd4 100644 --- a/python/x402/src/x402/clients/httpx.py +++ b/python/x402/src/x402/clients/httpx.py @@ -11,8 +11,9 @@ class HttpxHooks: - def __init__(self, client: x402Client): + def __init__(self, client: x402Client, httpx_client: Optional[AsyncClient] = None): self.client = client + self.httpx_client = httpx_client # Reference to the httpx client with hooks self._is_retry = False async def on_request(self, request: Request): @@ -28,6 +29,7 @@ async def on_response(self, response: Response) -> Response: # If this is a retry response, just return it if self._is_retry: + self._is_retry = False return response try: @@ -58,28 +60,38 @@ async def on_response(self, response: Response) -> Response: request.headers["X-Payment"] = payment_header request.headers["Access-Control-Expose-Headers"] = "X-Payment-Response" - # Retry the request - async with AsyncClient() as client: - retry_response = await client.send(request) - - # Copy the retry response data to the original response - response.status_code = retry_response.status_code - response.headers = retry_response.headers - response._content = retry_response._content - return response + # Retry the request using the same client (which has hooks) if available + if self.httpx_client: + retry_response = await self.httpx_client.send(request) + else: + # Fallback: create new client (less ideal but maintains backwards compatibility) + async with AsyncClient() as client: + retry_response = await client.send(request) + + # Copy the retry response data to the original response + response.status_code = retry_response.status_code + response.headers = retry_response.headers + response._content = retry_response._content + return response except PaymentError as e: self._is_retry = False raise e except Exception as e: self._is_retry = False - raise PaymentError(f"Failed to handle payment: {str(e)}") from e + # Get detailed error info + error_msg = str(e) if str(e) else repr(e) + error_type = type(e).__name__ + raise PaymentError( + f"Failed to handle payment: {error_type}: {error_msg}" + ) from e def x402_payment_hooks( account: Account, max_value: Optional[int] = None, payment_requirements_selector: Optional[PaymentSelectorCallable] = None, + httpx_client: Optional[AsyncClient] = None, ) -> Dict[str, List]: """Create httpx event hooks dictionary for handling 402 Payment Required responses. @@ -89,6 +101,7 @@ def x402_payment_hooks( payment_requirements_selector: Optional custom selector for payment requirements. Should be a callable that takes (accepts, network_filter, scheme_filter, max_value) and returns a PaymentRequirements object. + httpx_client: Optional AsyncClient instance to reuse for retries (recommended) Returns: Dictionary of event hooks that can be directly assigned to client.event_hooks @@ -100,8 +113,8 @@ def x402_payment_hooks( payment_requirements_selector=payment_requirements_selector, ) - # Create hooks - hooks = HttpxHooks(client) + # Create hooks with reference to httpx client for proper retry handling + hooks = HttpxHooks(client, httpx_client=httpx_client) # Return event hooks dictionary return { @@ -131,6 +144,19 @@ def __init__( **kwargs: Additional arguments to pass to AsyncClient """ super().__init__(**kwargs) - self.event_hooks = x402_payment_hooks( - account, max_value, payment_requirements_selector + + # Create x402Client + client = x402Client( + account, + max_value=max_value, + payment_requirements_selector=payment_requirements_selector, ) + + # Create hooks with reference to this httpx client so retries use the same client with hooks + hooks = HttpxHooks(client, httpx_client=self) + + # Install hooks + self.event_hooks = { + "request": [hooks.on_request], + "response": [hooks.on_response], + } diff --git a/python/x402/src/x402/facilitator.py b/python/x402/src/x402/facilitator.py index 56c8ac1e5..3bb251968 100644 --- a/python/x402/src/x402/facilitator.py +++ b/python/x402/src/x402/facilitator.py @@ -75,7 +75,8 @@ async def settle( custom_headers = await self.config["create_headers"]() headers.update(custom_headers.get("settle", {})) - async with httpx.AsyncClient() as client: + # Use longer timeout for blockchain settlement operations (15 seconds) + async with httpx.AsyncClient(timeout=15.0) as client: response = await client.post( f"{self.config['url']}/settle", json={ diff --git a/python/x402/src/x402/fastapi/middleware.py b/python/x402/src/x402/fastapi/middleware.py index c16f74c0d..54581514e 100644 --- a/python/x402/src/x402/fastapi/middleware.py +++ b/python/x402/src/x402/fastapi/middleware.py @@ -207,12 +207,16 @@ def x402_response(error: str): settle_response.model_dump_json(by_alias=True).encode("utf-8") ).decode("utf-8") else: - return x402_response( - "Settle failed: " - + (settle_response.error_reason or "Unknown error") + error_msg = "Settle failed: " + ( + settle_response.error_reason or "Unknown error" ) - except Exception: - return x402_response("Settle failed") + logger.error(error_msg) + return x402_response(error_msg) + except Exception as e: + error_msg = f"Settle failed: {type(e).__name__}: {str(e)}" + logger.error(error_msg) + logger.exception("Settlement exception details:") + return x402_response(error_msg) return response diff --git a/python/x402/tests/clients/test_httpx.py b/python/x402/tests/clients/test_httpx.py index 9ed1bf48c..b1efb7115 100644 --- a/python/x402/tests/clients/test_httpx.py +++ b/python/x402/tests/clients/test_httpx.py @@ -70,7 +70,7 @@ async def test_on_response_missing_request(hooks): # Don't set response.request at all to simulate missing request with pytest.raises( PaymentError, - match="Failed to handle payment: The request instance has not been set on this response.", + match="Failed to handle payment: RuntimeError: The request instance has not been set on this response.", ): await hooks.on_response(response) diff --git a/python/x402/uv.lock b/python/x402/uv.lock index f5273e79a..7b9775d13 100644 --- a/python/x402/uv.lock +++ b/python/x402/uv.lock @@ -1,14 +1,14 @@ version = 1 -revision = 1 +revision = 3 requires-python = ">=3.10" [[package]] name = "aiohappyeyeballs" version = "2.6.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760 } +sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760, upload-time = "2025-03-12T01:42:48.764Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265 }, + { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265, upload-time = "2025-03-12T01:42:47.083Z" }, ] [[package]] @@ -25,76 +25,76 @@ dependencies = [ { name = "propcache" }, { name = "yarl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f2/84/ea27e6ad14747d8c51afe201fb88a5c8282b6278256d30a6f71f730add88/aiohttp-3.12.12.tar.gz", hash = "sha256:05875595d2483d96cb61fa9f64e75262d7ac6251a7e3c811d8e26f7d721760bd", size = 7818643 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b4/d9/cfde93b9cb75253c716b8b1c773565209e3d4dd0772dd3ce3a2adcaa4639/aiohttp-3.12.12-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6f25e9d274d6abbb15254f76f100c3984d6b9ad6e66263cc60a465dd5c7e48f5", size = 702071 }, - { url = "https://files.pythonhosted.org/packages/ee/b0/46e38b8bc0bc645317deec32612af922ad9bafd85a1df255a67c2f2305f6/aiohttp-3.12.12-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b8ec3c1a1c13d24941b5b913607e57b9364e4c0ea69d5363181467492c4b2ba6", size = 478436 }, - { url = "https://files.pythonhosted.org/packages/8f/47/9c83db7f02ca71eb99a707ee13657fc24ba703b9babc59000c1f58ac1198/aiohttp-3.12.12-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:81ef2f9253c327c211cb7b06ea2edd90e637cf21c347b894d540466b8d304e08", size = 466213 }, - { url = "https://files.pythonhosted.org/packages/31/fe/4690c112e269e06c9182c32eeb43f3a95c4f203fdb095502717327993b80/aiohttp-3.12.12-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28ded835c3663fd41c9ad44685811b11e34e6ac9a7516a30bfce13f6abba4496", size = 1648258 }, - { url = "https://files.pythonhosted.org/packages/c8/1f/dacca6c7bbe69c77d8535d7a672478803e7078cc20fd9993fe09aa5be880/aiohttp-3.12.12-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a4b78ccf254fc10605b263996949a94ca3f50e4f9100e05137d6583e266b711e", size = 1622316 }, - { url = "https://files.pythonhosted.org/packages/ff/65/5ef47708f70524fcdecda735e0aea06e0feb7b8679e976e9bd1e7900f4c0/aiohttp-3.12.12-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f4a5af90d5232c41bb857568fe7d11ed84408653ec9da1ff999cc30258b9bd1", size = 1694723 }, - { url = "https://files.pythonhosted.org/packages/18/62/ab32bfa59f61292e4096c383316863e10001eec30e5b4b314856ed7156e2/aiohttp-3.12.12-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ffa5205c2f53f1120e93fdf2eca41b0f6344db131bc421246ee82c1e1038a14a", size = 1737037 }, - { url = "https://files.pythonhosted.org/packages/c1/b9/8b8f793081311e4f63aea63003a519064048e406c627c0454d6ed09dbc99/aiohttp-3.12.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f68301660f0d7a3eddfb84f959f78a8f9db98c76a49b5235508fa16edaad0f7c", size = 1641701 }, - { url = "https://files.pythonhosted.org/packages/1a/5c/72f510d42d626463b526345dcb8d14b390de89a9ba27a4717b518460bcd4/aiohttp-3.12.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db874d3b0c92fdbb553751af9d2733b378c25cc83cd9dfba87f12fafd2dc9cd5", size = 1581824 }, - { url = "https://files.pythonhosted.org/packages/61/6f/9378c9e1543d1c800ca040e21cd333b8f923ed051ae82b5a49ad96a6ac71/aiohttp-3.12.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5e53cf9c201b45838a2d07b1f2d5f7fec9666db7979240002ce64f9b8a1e0cf2", size = 1625674 }, - { url = "https://files.pythonhosted.org/packages/bb/85/4eef9bd52b497a405c88469cc099f4d15d33b149b5746ca4ef8ec6ab6388/aiohttp-3.12.12-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:8687cc5f32b4e328c233acd387d09a1b477007896b2f03c1c823a0fd05f63883", size = 1636460 }, - { url = "https://files.pythonhosted.org/packages/56/59/d8e954830b375fd658843cf7d88d27ca5e38dd5fcbfe62db3d1ba415d0fe/aiohttp-3.12.12-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5ee537ad29de716a3d8dc46c609908de0c25ffeebf93cd94a03d64cdc07d66d0", size = 1611912 }, - { url = "https://files.pythonhosted.org/packages/c3/5d/d0096a02f0515a38dff67db42d966273a12d17fc895e91466bfb4ab3875e/aiohttp-3.12.12-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:411f821be5af6af11dc5bed6c6c1dc6b6b25b91737d968ec2756f9baa75e5f9b", size = 1691498 }, - { url = "https://files.pythonhosted.org/packages/87/8d/d3a02397a6345c06623ae4648e2aef18fced858510b4a89d7262cfa4c683/aiohttp-3.12.12-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:f90319d94cf5f9786773237f24bd235a7b5959089f1af8ec1154580a3434b503", size = 1714737 }, - { url = "https://files.pythonhosted.org/packages/a9/40/b81000bf07c96db878703ea3dc561393d82441597729910459a8e06acc9a/aiohttp-3.12.12-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:73b148e606f34e9d513c451fd65efe1091772659ca5703338a396a99f60108ff", size = 1643078 }, - { url = "https://files.pythonhosted.org/packages/41/e5/31830642ce2c6d3dba74ed8a94933213df5e1651c1e8b4efc81cc88105ab/aiohttp-3.12.12-cp310-cp310-win32.whl", hash = "sha256:d40e7bfd577fdc8a92b72f35dfbdd3ec90f1bc8a72a42037fefe34d4eca2d4a1", size = 427517 }, - { url = "https://files.pythonhosted.org/packages/55/9d/a4e5379d44679e5f8d7d7ebecb0dae8cafab95176c4e753da6bc4b4aebb5/aiohttp-3.12.12-cp310-cp310-win_amd64.whl", hash = "sha256:65c7804a2343893d6dea9fce69811aea0a9ac47f68312cf2e3ee1668cd9a387f", size = 450725 }, - { url = "https://files.pythonhosted.org/packages/47/1f/b1b66e05dc3066a9ba7862d50e2e95b3871db82ccf9652568845f353eeba/aiohttp-3.12.12-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:38823fe0d8bc059b3eaedb263fe427d887c7032e72b4ef92c472953285f0e658", size = 709385 }, - { url = "https://files.pythonhosted.org/packages/43/e6/3230e42af16438b450b1e193c537fd3d2d31771dafda3c2105a8d11af707/aiohttp-3.12.12-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:10237f2c34711215d04ed21da63852ce023608299554080a45c576215d9df81c", size = 481660 }, - { url = "https://files.pythonhosted.org/packages/06/ba/cfa91fe5cc262535e1175b1522d8fcc09f9d6ad18b85241f4ee3be1d780f/aiohttp-3.12.12-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:563ec477c0dc6d56fc7f943a3475b5acdb399c7686c30f5a98ada24bb7562c7a", size = 469924 }, - { url = "https://files.pythonhosted.org/packages/9a/f0/5c706cfddd4769b55c0cda466aa6034412d39e416f0b30dda81c4a24616f/aiohttp-3.12.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3d05c46a61aca7c47df74afff818bc06a251ab95d95ff80b53665edfe1e0bdf", size = 1740116 }, - { url = "https://files.pythonhosted.org/packages/4d/9f/04dba2e1c8bee53c3c623d11a1f947c9e2712500f734dc0dfd06daad32ec/aiohttp-3.12.12-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:277c882916759b4a6b6dc7e2ceb124aad071b3c6456487808d9ab13e1b448d57", size = 1688784 }, - { url = "https://files.pythonhosted.org/packages/df/24/19d6d4c41fbf8304fe7c111fcc701e0aa5a2232ee3ac16272677a11f9cfe/aiohttp-3.12.12-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:216abf74b324b0f4e67041dd4fb2819613909a825904f8a51701fbcd40c09cd7", size = 1787575 }, - { url = "https://files.pythonhosted.org/packages/0c/59/01f4c55a1f91ad3b5255b2498b3a22362a3fe6ee9bc9ba1af3cc668244da/aiohttp-3.12.12-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65d6cefad286459b68e7f867b9586a821fb7f121057b88f02f536ef570992329", size = 1826621 }, - { url = "https://files.pythonhosted.org/packages/55/85/6357166918ff5025602a7cc41332c1ae7a5b57f2fe3da4d755ae30f24bd0/aiohttp-3.12.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:feaaaff61966b5f4b4eae0b79fc79427f49484e4cfa5ab7d138ecd933ab540a8", size = 1729082 }, - { url = "https://files.pythonhosted.org/packages/e3/ca/de3b5ccd5a2aa9352f6ec6f446565f6e1601ebb54860c94c686a9ff76660/aiohttp-3.12.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a05917780b7cad1755784b16cfaad806bc16029a93d15f063ca60185b7d9ba05", size = 1666159 }, - { url = "https://files.pythonhosted.org/packages/d1/69/a1006021a1d3244c0872ee75cd8da150e0098b3b2ec6945c225754d11a60/aiohttp-3.12.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:082c5ec6d262c1b2ee01c63f4fb9152c17f11692bf16f0f100ad94a7a287d456", size = 1714433 }, - { url = "https://files.pythonhosted.org/packages/d2/2a/15aa1179e9fbdd0d17cdf117b4296dedad098abb5a93f8e9c8ab4626f6ea/aiohttp-3.12.12-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:b265a3a8b379b38696ac78bdef943bdc4f4a5d6bed1a3fb5c75c6bab1ecea422", size = 1709590 }, - { url = "https://files.pythonhosted.org/packages/a2/f0/95ed9e21250815f1d1a0cd3e868a3f39400a16010ae59f19ddd4ccc4e787/aiohttp-3.12.12-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:2e0f2e208914ecbc4b2a3b7b4daa759d0c587d9a0b451bb0835ac47fae7fa735", size = 1689776 }, - { url = "https://files.pythonhosted.org/packages/81/4d/370ecc133c648c98a85445f2d331c1272859c89cd52c29a293015bc352c7/aiohttp-3.12.12-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:9923b025845b72f64d167bca221113377c8ffabd0a351dc18fb839d401ee8e22", size = 1783378 }, - { url = "https://files.pythonhosted.org/packages/a8/86/414e3dae7e07caf6b02cd75d7148d0d8673d4c5077f407be3627d6e33fac/aiohttp-3.12.12-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:1ebb213445900527831fecc70e185bf142fdfe5f2a691075f22d63c65ee3c35a", size = 1803841 }, - { url = "https://files.pythonhosted.org/packages/88/df/486f10df681cd1a8c898acc8dc2edbd46ffb088b886757b71ae362bf44d3/aiohttp-3.12.12-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6fc369fb273a8328077d37798b77c1e65676709af5c182cb74bd169ca9defe81", size = 1716896 }, - { url = "https://files.pythonhosted.org/packages/07/1e/1cacaf5d838869432e96ece1580d0b51494ebb66351f0e8118b74b38d2f0/aiohttp-3.12.12-cp311-cp311-win32.whl", hash = "sha256:58ecd10fda6a44c311cd3742cfd2aea8c4c600338e9f27cb37434d9f5ca9ddaa", size = 427030 }, - { url = "https://files.pythonhosted.org/packages/30/dd/e89c1d190da2c84e0ca03c2970b9988a9c56005d18db7f447cf62b3ae6d0/aiohttp-3.12.12-cp311-cp311-win_amd64.whl", hash = "sha256:b0066e88f30be00badffb5ef8f2281532b9a9020863d873ae15f7c147770b6ec", size = 451419 }, - { url = "https://files.pythonhosted.org/packages/df/e6/df14ec151942818ecc5e685fa8a4b07d3d3d8a9e4a7d2701047c89290551/aiohttp-3.12.12-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:98451ce9ce229d092f278a74a7c2a06b3aa72984673c87796126d7ccade893e9", size = 700494 }, - { url = "https://files.pythonhosted.org/packages/4f/dc/7bc6e17adcd7a82b0d0317ad3e792ac22c93fb672077f0eade93e8d70182/aiohttp-3.12.12-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:adbac7286d89245e1aff42e948503fdc6edf6d5d65c8e305a67c40f6a8fb95f4", size = 475095 }, - { url = "https://files.pythonhosted.org/packages/80/fd/c4e8846ad9d9ecdb7d5ba96de65b7bf2c1582f0b2732f2023080c1c05255/aiohttp-3.12.12-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0728882115bfa85cbd8d0f664c8ccc0cfd5bd3789dd837596785450ae52fac31", size = 467929 }, - { url = "https://files.pythonhosted.org/packages/70/40/abebcf5c81f5e65b4379c05929773be2731ce12414264d3e0fe09ee241eb/aiohttp-3.12.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6bf3b9d9e767f9d0e09fb1a31516410fc741a62cc08754578c40abc497d09540", size = 1714729 }, - { url = "https://files.pythonhosted.org/packages/8e/67/4c4f96ef6f16405e7c5205ab3c28852c7e904493b6ddc1c744dda1c97a81/aiohttp-3.12.12-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c944860e86b9f77a462321a440ccf6fa10f5719bb9d026f6b0b11307b1c96c7b", size = 1697380 }, - { url = "https://files.pythonhosted.org/packages/e9/a2/dae9ebea4caa8030170c0237e55fa0960df44b3596a849ab9ea621964054/aiohttp-3.12.12-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b1979e1f0c98c06fd0cd940988833b102fa3aa56751f6c40ffe85cabc51f6fd", size = 1752474 }, - { url = "https://files.pythonhosted.org/packages/31/ef/f3d9073565ac7ad5257aaa1490ebfc2f182dfc817d3ccfd38c8ab35b2247/aiohttp-3.12.12-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:120b7dd084e96cfdad85acea2ce1e7708c70a26db913eabb8d7b417c728f5d84", size = 1798631 }, - { url = "https://files.pythonhosted.org/packages/8b/0b/8b1978662274c80c8e4a739d9be1ae9ef25e5ce42b55838d6a9d1a4e3497/aiohttp-3.12.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e58f5ae79649ffa247081c2e8c85e31d29623cf2a3137dda985ae05c9478aae", size = 1718071 }, - { url = "https://files.pythonhosted.org/packages/56/aa/35786137db867901b41cb3d2c19c0f4c56dfe581694dba99dec2683d8f8d/aiohttp-3.12.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9aa5f049e3e2745b0141f13e5a64e7c48b1a1427ed18bbb7957b348f282fee56", size = 1633871 }, - { url = "https://files.pythonhosted.org/packages/63/1d/34d45497dd04d08d662ecda875c44e91d271bbc5d21f4c9e4cbd3ddf7ae2/aiohttp-3.12.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7163cc9cf3722d90f1822f8a38b211e3ae2fc651c63bb55449f03dc1b3ff1d44", size = 1694933 }, - { url = "https://files.pythonhosted.org/packages/29/c7/41e09a4517449eabbb0a7fe6d60f584fe5b21d4bff761197eb0b81e70034/aiohttp-3.12.12-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ef97c4d035b721de6607f3980fa3e4ef0ec3aca76474b5789b7fac286a8c4e23", size = 1716386 }, - { url = "https://files.pythonhosted.org/packages/3a/32/907bd2010b51b70de5314ad707dfc4e898ea0011ff3d678cdf43d6f8980a/aiohttp-3.12.12-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:1c14448d6a86acadc3f7b2f4cc385d1fb390acb6f37dce27f86fe629410d92e3", size = 1657039 }, - { url = "https://files.pythonhosted.org/packages/60/27/8d87344a33346dcd39273adc33060aeb135e0ef70d1d6e71a3b03894a8e9/aiohttp-3.12.12-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a1b6df6255cfc493454c79221183d64007dd5080bcda100db29b7ff181b8832c", size = 1736599 }, - { url = "https://files.pythonhosted.org/packages/ca/45/57c7ef1af694a6d0906abab6edde03787c8c6b0cf5d8359b69d1eb0679df/aiohttp-3.12.12-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:60fc7338dfb0626c2927bfbac4785de3ea2e2bbe3d328ba5f3ece123edda4977", size = 1764575 }, - { url = "https://files.pythonhosted.org/packages/2a/cc/b1f918cd702efa9ead9d41f89214e9225cda4e5d013d6eed7f1915c17d0a/aiohttp-3.12.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d2afc72207ef4c9d4ca9fcd00689a6a37ef2d625600c3d757b5c2b80c9d0cf9a", size = 1724184 }, - { url = "https://files.pythonhosted.org/packages/47/55/089762ee32c2a2e0f523d9ab38c9da2a344cac0e0cc8d16ecf206517ef7e/aiohttp-3.12.12-cp312-cp312-win32.whl", hash = "sha256:8098a48f93b2cbcdb5778e7c9a0e0375363e40ad692348e6e65c3b70d593b27c", size = 421762 }, - { url = "https://files.pythonhosted.org/packages/ab/47/151f657e429972916f61399bd52b410e9072d5a2cae1b794f890930e5797/aiohttp-3.12.12-cp312-cp312-win_amd64.whl", hash = "sha256:d1c1879b2e0fc337d7a1b63fe950553c2b9e93c071cf95928aeea1902d441403", size = 447863 }, - { url = "https://files.pythonhosted.org/packages/ee/3e/396a7d1c47aa7a74612b186dc716857506c61afac72337a7a96215c2a124/aiohttp-3.12.12-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ea5d604318234427929d486954e3199aded65f41593ac57aa0241ab93dda3d15", size = 694901 }, - { url = "https://files.pythonhosted.org/packages/cc/97/235e48eadf73a1854b4d4da29b88d00049309d897d55a511e1cbe4412603/aiohttp-3.12.12-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e03ff38250b8b572dce6fcd7b6fb6ee398bb8a59e6aa199009c5322d721df4fc", size = 472552 }, - { url = "https://files.pythonhosted.org/packages/6b/73/cd7c9439e8cab4113650541017c6524bd0e675b219dfdbbf945a78305e3f/aiohttp-3.12.12-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:71125b1fc2b6a94bccc63bbece620906a4dead336d2051f8af9cbf04480bc5af", size = 464853 }, - { url = "https://files.pythonhosted.org/packages/d1/33/eea88ee55ed4b3f74732d9fc773e6fcf134a2971a19c7ecc49a291e7e57f/aiohttp-3.12.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:784a66f9f853a22c6b8c2bd0ff157f9b879700f468d6d72cfa99167df08c5c9c", size = 1703671 }, - { url = "https://files.pythonhosted.org/packages/2a/e3/a67ecf9c154b13bad9e2a86ea3782a4b73e889343ffde8c1aadcf9099c09/aiohttp-3.12.12-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a5be0b58670b54301404bd1840e4902570a1c3be00358e2700919cb1ea73c438", size = 1684934 }, - { url = "https://files.pythonhosted.org/packages/89/f0/3aaea866531be2f2fcf3a87607e1f55fa72e6ce5acd6b058941a4fc35e15/aiohttp-3.12.12-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8f13566fc7bf5a728275b434bc3bdea87a7ed3ad5f734102b02ca59d9b510f", size = 1737004 }, - { url = "https://files.pythonhosted.org/packages/a7/7a/15867a4c7d39d8fd9bd02191cf60b1d06415fc407bbd4ff2f9660845f1cb/aiohttp-3.12.12-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d736e57d1901683bc9be648aa308cb73e646252c74b4c639c35dcd401ed385ea", size = 1786378 }, - { url = "https://files.pythonhosted.org/packages/bd/61/82b15f87088b35705e01fce55806241b45a1099b3470bbca0bed8ee98662/aiohttp-3.12.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2007eaa7aae9102f211c519d1ec196bd3cecb1944a095db19eeaf132b798738", size = 1708707 }, - { url = "https://files.pythonhosted.org/packages/28/f2/aed0786d5a1c2ed1f5a13ff2a98baacc27206b81d93812da28fc49d8a5d0/aiohttp-3.12.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a813e61583cab6d5cdbaa34bc28863acdb92f9f46e11de1b3b9251a1e8238f6", size = 1622410 }, - { url = "https://files.pythonhosted.org/packages/17/54/8305f49a960376136ada977be1370fddb584c63d40bd1b9bef59469f28c7/aiohttp-3.12.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e408293aa910b0aea48b86a28eace41d497a85ba16c20f619f0c604597ef996c", size = 1675435 }, - { url = "https://files.pythonhosted.org/packages/bb/dc/0a55350025bc297265cfa6c6b1b1f7508f4226ca3238697cbe5e772a7d76/aiohttp-3.12.12-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:f3d31faf290f5a30acba46b388465b67c6dbe8655d183e9efe2f6a1d594e6d9d", size = 1707099 }, - { url = "https://files.pythonhosted.org/packages/d8/70/d949a1612b996e49d540c10ed77a0a1465c482a590e9a59c1c7897746119/aiohttp-3.12.12-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0b84731697325b023902aa643bd1726d999f5bc7854bc28b17ff410a81151d4b", size = 1649693 }, - { url = "https://files.pythonhosted.org/packages/c1/ea/fb87beb7135e25576a1e6fbe98106c037d9fcf1543f19108f9ceb73c192c/aiohttp-3.12.12-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a324c6852b6e327811748446e56cc9bb6eaa58710557922183175816e82a4234", size = 1725825 }, - { url = "https://files.pythonhosted.org/packages/f1/1f/adbeb3e440d49b733cef499ace94723ab1fe9fb516425e219379e03b7c9a/aiohttp-3.12.12-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:22fd867fbd72612dcf670c90486dbcbaf702cb807fb0b42bc0b7a142a573574a", size = 1759300 }, - { url = "https://files.pythonhosted.org/packages/f2/c1/2fe007ad930f409d0d7fd9916cd55ec9b78b6a611a237424266ed71da48b/aiohttp-3.12.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3e092f1a970223794a4bf620a26c0e4e4e8e36bccae9b0b5da35e6d8ee598a03", size = 1708189 }, - { url = "https://files.pythonhosted.org/packages/85/5e/ed3ed640fafae3972eae6cd26f66240108cf62452ac8128d59970d538cb1/aiohttp-3.12.12-cp313-cp313-win32.whl", hash = "sha256:7f5f5eb8717ef8ba15ab35fcde5a70ad28bbdc34157595d1cddd888a985f5aae", size = 420783 }, - { url = "https://files.pythonhosted.org/packages/a6/db/57d2bb4af52dd0c6f62c42c7d34b82495b2902e50440134f70bfb7ee0fdd/aiohttp-3.12.12-cp313-cp313-win_amd64.whl", hash = "sha256:ace2499bdd03c329c054dc4b47361f2b19d5aa470f7db5c7e0e989336761b33c", size = 446721 }, +sdist = { url = "https://files.pythonhosted.org/packages/f2/84/ea27e6ad14747d8c51afe201fb88a5c8282b6278256d30a6f71f730add88/aiohttp-3.12.12.tar.gz", hash = "sha256:05875595d2483d96cb61fa9f64e75262d7ac6251a7e3c811d8e26f7d721760bd", size = 7818643, upload-time = "2025-06-10T05:22:00.247Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/d9/cfde93b9cb75253c716b8b1c773565209e3d4dd0772dd3ce3a2adcaa4639/aiohttp-3.12.12-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6f25e9d274d6abbb15254f76f100c3984d6b9ad6e66263cc60a465dd5c7e48f5", size = 702071, upload-time = "2025-06-10T05:18:23.986Z" }, + { url = "https://files.pythonhosted.org/packages/ee/b0/46e38b8bc0bc645317deec32612af922ad9bafd85a1df255a67c2f2305f6/aiohttp-3.12.12-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b8ec3c1a1c13d24941b5b913607e57b9364e4c0ea69d5363181467492c4b2ba6", size = 478436, upload-time = "2025-06-10T05:18:28.411Z" }, + { url = "https://files.pythonhosted.org/packages/8f/47/9c83db7f02ca71eb99a707ee13657fc24ba703b9babc59000c1f58ac1198/aiohttp-3.12.12-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:81ef2f9253c327c211cb7b06ea2edd90e637cf21c347b894d540466b8d304e08", size = 466213, upload-time = "2025-06-10T05:18:30.706Z" }, + { url = "https://files.pythonhosted.org/packages/31/fe/4690c112e269e06c9182c32eeb43f3a95c4f203fdb095502717327993b80/aiohttp-3.12.12-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28ded835c3663fd41c9ad44685811b11e34e6ac9a7516a30bfce13f6abba4496", size = 1648258, upload-time = "2025-06-10T05:18:32.498Z" }, + { url = "https://files.pythonhosted.org/packages/c8/1f/dacca6c7bbe69c77d8535d7a672478803e7078cc20fd9993fe09aa5be880/aiohttp-3.12.12-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a4b78ccf254fc10605b263996949a94ca3f50e4f9100e05137d6583e266b711e", size = 1622316, upload-time = "2025-06-10T05:18:34.357Z" }, + { url = "https://files.pythonhosted.org/packages/ff/65/5ef47708f70524fcdecda735e0aea06e0feb7b8679e976e9bd1e7900f4c0/aiohttp-3.12.12-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f4a5af90d5232c41bb857568fe7d11ed84408653ec9da1ff999cc30258b9bd1", size = 1694723, upload-time = "2025-06-10T05:18:36.858Z" }, + { url = "https://files.pythonhosted.org/packages/18/62/ab32bfa59f61292e4096c383316863e10001eec30e5b4b314856ed7156e2/aiohttp-3.12.12-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ffa5205c2f53f1120e93fdf2eca41b0f6344db131bc421246ee82c1e1038a14a", size = 1737037, upload-time = "2025-06-10T05:18:39.663Z" }, + { url = "https://files.pythonhosted.org/packages/c1/b9/8b8f793081311e4f63aea63003a519064048e406c627c0454d6ed09dbc99/aiohttp-3.12.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f68301660f0d7a3eddfb84f959f78a8f9db98c76a49b5235508fa16edaad0f7c", size = 1641701, upload-time = "2025-06-10T05:18:41.666Z" }, + { url = "https://files.pythonhosted.org/packages/1a/5c/72f510d42d626463b526345dcb8d14b390de89a9ba27a4717b518460bcd4/aiohttp-3.12.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db874d3b0c92fdbb553751af9d2733b378c25cc83cd9dfba87f12fafd2dc9cd5", size = 1581824, upload-time = "2025-06-10T05:18:44.136Z" }, + { url = "https://files.pythonhosted.org/packages/61/6f/9378c9e1543d1c800ca040e21cd333b8f923ed051ae82b5a49ad96a6ac71/aiohttp-3.12.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5e53cf9c201b45838a2d07b1f2d5f7fec9666db7979240002ce64f9b8a1e0cf2", size = 1625674, upload-time = "2025-06-10T05:18:46.716Z" }, + { url = "https://files.pythonhosted.org/packages/bb/85/4eef9bd52b497a405c88469cc099f4d15d33b149b5746ca4ef8ec6ab6388/aiohttp-3.12.12-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:8687cc5f32b4e328c233acd387d09a1b477007896b2f03c1c823a0fd05f63883", size = 1636460, upload-time = "2025-06-10T05:18:49.305Z" }, + { url = "https://files.pythonhosted.org/packages/56/59/d8e954830b375fd658843cf7d88d27ca5e38dd5fcbfe62db3d1ba415d0fe/aiohttp-3.12.12-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5ee537ad29de716a3d8dc46c609908de0c25ffeebf93cd94a03d64cdc07d66d0", size = 1611912, upload-time = "2025-06-10T05:18:51.694Z" }, + { url = "https://files.pythonhosted.org/packages/c3/5d/d0096a02f0515a38dff67db42d966273a12d17fc895e91466bfb4ab3875e/aiohttp-3.12.12-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:411f821be5af6af11dc5bed6c6c1dc6b6b25b91737d968ec2756f9baa75e5f9b", size = 1691498, upload-time = "2025-06-10T05:18:54.36Z" }, + { url = "https://files.pythonhosted.org/packages/87/8d/d3a02397a6345c06623ae4648e2aef18fced858510b4a89d7262cfa4c683/aiohttp-3.12.12-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:f90319d94cf5f9786773237f24bd235a7b5959089f1af8ec1154580a3434b503", size = 1714737, upload-time = "2025-06-10T05:18:56.806Z" }, + { url = "https://files.pythonhosted.org/packages/a9/40/b81000bf07c96db878703ea3dc561393d82441597729910459a8e06acc9a/aiohttp-3.12.12-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:73b148e606f34e9d513c451fd65efe1091772659ca5703338a396a99f60108ff", size = 1643078, upload-time = "2025-06-10T05:18:59.33Z" }, + { url = "https://files.pythonhosted.org/packages/41/e5/31830642ce2c6d3dba74ed8a94933213df5e1651c1e8b4efc81cc88105ab/aiohttp-3.12.12-cp310-cp310-win32.whl", hash = "sha256:d40e7bfd577fdc8a92b72f35dfbdd3ec90f1bc8a72a42037fefe34d4eca2d4a1", size = 427517, upload-time = "2025-06-10T05:19:01.535Z" }, + { url = "https://files.pythonhosted.org/packages/55/9d/a4e5379d44679e5f8d7d7ebecb0dae8cafab95176c4e753da6bc4b4aebb5/aiohttp-3.12.12-cp310-cp310-win_amd64.whl", hash = "sha256:65c7804a2343893d6dea9fce69811aea0a9ac47f68312cf2e3ee1668cd9a387f", size = 450725, upload-time = "2025-06-10T05:19:03.874Z" }, + { url = "https://files.pythonhosted.org/packages/47/1f/b1b66e05dc3066a9ba7862d50e2e95b3871db82ccf9652568845f353eeba/aiohttp-3.12.12-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:38823fe0d8bc059b3eaedb263fe427d887c7032e72b4ef92c472953285f0e658", size = 709385, upload-time = "2025-06-10T05:19:05.763Z" }, + { url = "https://files.pythonhosted.org/packages/43/e6/3230e42af16438b450b1e193c537fd3d2d31771dafda3c2105a8d11af707/aiohttp-3.12.12-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:10237f2c34711215d04ed21da63852ce023608299554080a45c576215d9df81c", size = 481660, upload-time = "2025-06-10T05:19:08.332Z" }, + { url = "https://files.pythonhosted.org/packages/06/ba/cfa91fe5cc262535e1175b1522d8fcc09f9d6ad18b85241f4ee3be1d780f/aiohttp-3.12.12-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:563ec477c0dc6d56fc7f943a3475b5acdb399c7686c30f5a98ada24bb7562c7a", size = 469924, upload-time = "2025-06-10T05:19:10.342Z" }, + { url = "https://files.pythonhosted.org/packages/9a/f0/5c706cfddd4769b55c0cda466aa6034412d39e416f0b30dda81c4a24616f/aiohttp-3.12.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3d05c46a61aca7c47df74afff818bc06a251ab95d95ff80b53665edfe1e0bdf", size = 1740116, upload-time = "2025-06-10T05:19:12.783Z" }, + { url = "https://files.pythonhosted.org/packages/4d/9f/04dba2e1c8bee53c3c623d11a1f947c9e2712500f734dc0dfd06daad32ec/aiohttp-3.12.12-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:277c882916759b4a6b6dc7e2ceb124aad071b3c6456487808d9ab13e1b448d57", size = 1688784, upload-time = "2025-06-10T05:19:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/df/24/19d6d4c41fbf8304fe7c111fcc701e0aa5a2232ee3ac16272677a11f9cfe/aiohttp-3.12.12-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:216abf74b324b0f4e67041dd4fb2819613909a825904f8a51701fbcd40c09cd7", size = 1787575, upload-time = "2025-06-10T05:19:18.586Z" }, + { url = "https://files.pythonhosted.org/packages/0c/59/01f4c55a1f91ad3b5255b2498b3a22362a3fe6ee9bc9ba1af3cc668244da/aiohttp-3.12.12-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65d6cefad286459b68e7f867b9586a821fb7f121057b88f02f536ef570992329", size = 1826621, upload-time = "2025-06-10T05:19:21.284Z" }, + { url = "https://files.pythonhosted.org/packages/55/85/6357166918ff5025602a7cc41332c1ae7a5b57f2fe3da4d755ae30f24bd0/aiohttp-3.12.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:feaaaff61966b5f4b4eae0b79fc79427f49484e4cfa5ab7d138ecd933ab540a8", size = 1729082, upload-time = "2025-06-10T05:19:23.307Z" }, + { url = "https://files.pythonhosted.org/packages/e3/ca/de3b5ccd5a2aa9352f6ec6f446565f6e1601ebb54860c94c686a9ff76660/aiohttp-3.12.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a05917780b7cad1755784b16cfaad806bc16029a93d15f063ca60185b7d9ba05", size = 1666159, upload-time = "2025-06-10T05:19:25.929Z" }, + { url = "https://files.pythonhosted.org/packages/d1/69/a1006021a1d3244c0872ee75cd8da150e0098b3b2ec6945c225754d11a60/aiohttp-3.12.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:082c5ec6d262c1b2ee01c63f4fb9152c17f11692bf16f0f100ad94a7a287d456", size = 1714433, upload-time = "2025-06-10T05:19:28.044Z" }, + { url = "https://files.pythonhosted.org/packages/d2/2a/15aa1179e9fbdd0d17cdf117b4296dedad098abb5a93f8e9c8ab4626f6ea/aiohttp-3.12.12-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:b265a3a8b379b38696ac78bdef943bdc4f4a5d6bed1a3fb5c75c6bab1ecea422", size = 1709590, upload-time = "2025-06-10T05:19:30.165Z" }, + { url = "https://files.pythonhosted.org/packages/a2/f0/95ed9e21250815f1d1a0cd3e868a3f39400a16010ae59f19ddd4ccc4e787/aiohttp-3.12.12-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:2e0f2e208914ecbc4b2a3b7b4daa759d0c587d9a0b451bb0835ac47fae7fa735", size = 1689776, upload-time = "2025-06-10T05:19:32.965Z" }, + { url = "https://files.pythonhosted.org/packages/81/4d/370ecc133c648c98a85445f2d331c1272859c89cd52c29a293015bc352c7/aiohttp-3.12.12-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:9923b025845b72f64d167bca221113377c8ffabd0a351dc18fb839d401ee8e22", size = 1783378, upload-time = "2025-06-10T05:19:35.14Z" }, + { url = "https://files.pythonhosted.org/packages/a8/86/414e3dae7e07caf6b02cd75d7148d0d8673d4c5077f407be3627d6e33fac/aiohttp-3.12.12-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:1ebb213445900527831fecc70e185bf142fdfe5f2a691075f22d63c65ee3c35a", size = 1803841, upload-time = "2025-06-10T05:19:37.41Z" }, + { url = "https://files.pythonhosted.org/packages/88/df/486f10df681cd1a8c898acc8dc2edbd46ffb088b886757b71ae362bf44d3/aiohttp-3.12.12-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6fc369fb273a8328077d37798b77c1e65676709af5c182cb74bd169ca9defe81", size = 1716896, upload-time = "2025-06-10T05:19:40.172Z" }, + { url = "https://files.pythonhosted.org/packages/07/1e/1cacaf5d838869432e96ece1580d0b51494ebb66351f0e8118b74b38d2f0/aiohttp-3.12.12-cp311-cp311-win32.whl", hash = "sha256:58ecd10fda6a44c311cd3742cfd2aea8c4c600338e9f27cb37434d9f5ca9ddaa", size = 427030, upload-time = "2025-06-10T05:19:42.152Z" }, + { url = "https://files.pythonhosted.org/packages/30/dd/e89c1d190da2c84e0ca03c2970b9988a9c56005d18db7f447cf62b3ae6d0/aiohttp-3.12.12-cp311-cp311-win_amd64.whl", hash = "sha256:b0066e88f30be00badffb5ef8f2281532b9a9020863d873ae15f7c147770b6ec", size = 451419, upload-time = "2025-06-10T05:19:44.176Z" }, + { url = "https://files.pythonhosted.org/packages/df/e6/df14ec151942818ecc5e685fa8a4b07d3d3d8a9e4a7d2701047c89290551/aiohttp-3.12.12-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:98451ce9ce229d092f278a74a7c2a06b3aa72984673c87796126d7ccade893e9", size = 700494, upload-time = "2025-06-10T05:19:46.18Z" }, + { url = "https://files.pythonhosted.org/packages/4f/dc/7bc6e17adcd7a82b0d0317ad3e792ac22c93fb672077f0eade93e8d70182/aiohttp-3.12.12-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:adbac7286d89245e1aff42e948503fdc6edf6d5d65c8e305a67c40f6a8fb95f4", size = 475095, upload-time = "2025-06-10T05:19:48.246Z" }, + { url = "https://files.pythonhosted.org/packages/80/fd/c4e8846ad9d9ecdb7d5ba96de65b7bf2c1582f0b2732f2023080c1c05255/aiohttp-3.12.12-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0728882115bfa85cbd8d0f664c8ccc0cfd5bd3789dd837596785450ae52fac31", size = 467929, upload-time = "2025-06-10T05:19:50.79Z" }, + { url = "https://files.pythonhosted.org/packages/70/40/abebcf5c81f5e65b4379c05929773be2731ce12414264d3e0fe09ee241eb/aiohttp-3.12.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6bf3b9d9e767f9d0e09fb1a31516410fc741a62cc08754578c40abc497d09540", size = 1714729, upload-time = "2025-06-10T05:19:52.989Z" }, + { url = "https://files.pythonhosted.org/packages/8e/67/4c4f96ef6f16405e7c5205ab3c28852c7e904493b6ddc1c744dda1c97a81/aiohttp-3.12.12-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c944860e86b9f77a462321a440ccf6fa10f5719bb9d026f6b0b11307b1c96c7b", size = 1697380, upload-time = "2025-06-10T05:19:55.832Z" }, + { url = "https://files.pythonhosted.org/packages/e9/a2/dae9ebea4caa8030170c0237e55fa0960df44b3596a849ab9ea621964054/aiohttp-3.12.12-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b1979e1f0c98c06fd0cd940988833b102fa3aa56751f6c40ffe85cabc51f6fd", size = 1752474, upload-time = "2025-06-10T05:19:58.007Z" }, + { url = "https://files.pythonhosted.org/packages/31/ef/f3d9073565ac7ad5257aaa1490ebfc2f182dfc817d3ccfd38c8ab35b2247/aiohttp-3.12.12-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:120b7dd084e96cfdad85acea2ce1e7708c70a26db913eabb8d7b417c728f5d84", size = 1798631, upload-time = "2025-06-10T05:20:00.393Z" }, + { url = "https://files.pythonhosted.org/packages/8b/0b/8b1978662274c80c8e4a739d9be1ae9ef25e5ce42b55838d6a9d1a4e3497/aiohttp-3.12.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e58f5ae79649ffa247081c2e8c85e31d29623cf2a3137dda985ae05c9478aae", size = 1718071, upload-time = "2025-06-10T05:20:02.812Z" }, + { url = "https://files.pythonhosted.org/packages/56/aa/35786137db867901b41cb3d2c19c0f4c56dfe581694dba99dec2683d8f8d/aiohttp-3.12.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9aa5f049e3e2745b0141f13e5a64e7c48b1a1427ed18bbb7957b348f282fee56", size = 1633871, upload-time = "2025-06-10T05:20:05.127Z" }, + { url = "https://files.pythonhosted.org/packages/63/1d/34d45497dd04d08d662ecda875c44e91d271bbc5d21f4c9e4cbd3ddf7ae2/aiohttp-3.12.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7163cc9cf3722d90f1822f8a38b211e3ae2fc651c63bb55449f03dc1b3ff1d44", size = 1694933, upload-time = "2025-06-10T05:20:07.431Z" }, + { url = "https://files.pythonhosted.org/packages/29/c7/41e09a4517449eabbb0a7fe6d60f584fe5b21d4bff761197eb0b81e70034/aiohttp-3.12.12-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ef97c4d035b721de6607f3980fa3e4ef0ec3aca76474b5789b7fac286a8c4e23", size = 1716386, upload-time = "2025-06-10T05:20:09.787Z" }, + { url = "https://files.pythonhosted.org/packages/3a/32/907bd2010b51b70de5314ad707dfc4e898ea0011ff3d678cdf43d6f8980a/aiohttp-3.12.12-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:1c14448d6a86acadc3f7b2f4cc385d1fb390acb6f37dce27f86fe629410d92e3", size = 1657039, upload-time = "2025-06-10T05:20:12.198Z" }, + { url = "https://files.pythonhosted.org/packages/60/27/8d87344a33346dcd39273adc33060aeb135e0ef70d1d6e71a3b03894a8e9/aiohttp-3.12.12-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a1b6df6255cfc493454c79221183d64007dd5080bcda100db29b7ff181b8832c", size = 1736599, upload-time = "2025-06-10T05:20:14.519Z" }, + { url = "https://files.pythonhosted.org/packages/ca/45/57c7ef1af694a6d0906abab6edde03787c8c6b0cf5d8359b69d1eb0679df/aiohttp-3.12.12-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:60fc7338dfb0626c2927bfbac4785de3ea2e2bbe3d328ba5f3ece123edda4977", size = 1764575, upload-time = "2025-06-10T05:20:16.993Z" }, + { url = "https://files.pythonhosted.org/packages/2a/cc/b1f918cd702efa9ead9d41f89214e9225cda4e5d013d6eed7f1915c17d0a/aiohttp-3.12.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d2afc72207ef4c9d4ca9fcd00689a6a37ef2d625600c3d757b5c2b80c9d0cf9a", size = 1724184, upload-time = "2025-06-10T05:20:19.296Z" }, + { url = "https://files.pythonhosted.org/packages/47/55/089762ee32c2a2e0f523d9ab38c9da2a344cac0e0cc8d16ecf206517ef7e/aiohttp-3.12.12-cp312-cp312-win32.whl", hash = "sha256:8098a48f93b2cbcdb5778e7c9a0e0375363e40ad692348e6e65c3b70d593b27c", size = 421762, upload-time = "2025-06-10T05:20:22.063Z" }, + { url = "https://files.pythonhosted.org/packages/ab/47/151f657e429972916f61399bd52b410e9072d5a2cae1b794f890930e5797/aiohttp-3.12.12-cp312-cp312-win_amd64.whl", hash = "sha256:d1c1879b2e0fc337d7a1b63fe950553c2b9e93c071cf95928aeea1902d441403", size = 447863, upload-time = "2025-06-10T05:20:24.326Z" }, + { url = "https://files.pythonhosted.org/packages/ee/3e/396a7d1c47aa7a74612b186dc716857506c61afac72337a7a96215c2a124/aiohttp-3.12.12-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ea5d604318234427929d486954e3199aded65f41593ac57aa0241ab93dda3d15", size = 694901, upload-time = "2025-06-10T05:20:26.58Z" }, + { url = "https://files.pythonhosted.org/packages/cc/97/235e48eadf73a1854b4d4da29b88d00049309d897d55a511e1cbe4412603/aiohttp-3.12.12-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e03ff38250b8b572dce6fcd7b6fb6ee398bb8a59e6aa199009c5322d721df4fc", size = 472552, upload-time = "2025-06-10T05:20:28.957Z" }, + { url = "https://files.pythonhosted.org/packages/6b/73/cd7c9439e8cab4113650541017c6524bd0e675b219dfdbbf945a78305e3f/aiohttp-3.12.12-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:71125b1fc2b6a94bccc63bbece620906a4dead336d2051f8af9cbf04480bc5af", size = 464853, upload-time = "2025-06-10T05:20:31.652Z" }, + { url = "https://files.pythonhosted.org/packages/d1/33/eea88ee55ed4b3f74732d9fc773e6fcf134a2971a19c7ecc49a291e7e57f/aiohttp-3.12.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:784a66f9f853a22c6b8c2bd0ff157f9b879700f468d6d72cfa99167df08c5c9c", size = 1703671, upload-time = "2025-06-10T05:20:33.969Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e3/a67ecf9c154b13bad9e2a86ea3782a4b73e889343ffde8c1aadcf9099c09/aiohttp-3.12.12-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a5be0b58670b54301404bd1840e4902570a1c3be00358e2700919cb1ea73c438", size = 1684934, upload-time = "2025-06-10T05:20:36.721Z" }, + { url = "https://files.pythonhosted.org/packages/89/f0/3aaea866531be2f2fcf3a87607e1f55fa72e6ce5acd6b058941a4fc35e15/aiohttp-3.12.12-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8f13566fc7bf5a728275b434bc3bdea87a7ed3ad5f734102b02ca59d9b510f", size = 1737004, upload-time = "2025-06-10T05:20:39.533Z" }, + { url = "https://files.pythonhosted.org/packages/a7/7a/15867a4c7d39d8fd9bd02191cf60b1d06415fc407bbd4ff2f9660845f1cb/aiohttp-3.12.12-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d736e57d1901683bc9be648aa308cb73e646252c74b4c639c35dcd401ed385ea", size = 1786378, upload-time = "2025-06-10T05:20:42.03Z" }, + { url = "https://files.pythonhosted.org/packages/bd/61/82b15f87088b35705e01fce55806241b45a1099b3470bbca0bed8ee98662/aiohttp-3.12.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2007eaa7aae9102f211c519d1ec196bd3cecb1944a095db19eeaf132b798738", size = 1708707, upload-time = "2025-06-10T05:20:44.474Z" }, + { url = "https://files.pythonhosted.org/packages/28/f2/aed0786d5a1c2ed1f5a13ff2a98baacc27206b81d93812da28fc49d8a5d0/aiohttp-3.12.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a813e61583cab6d5cdbaa34bc28863acdb92f9f46e11de1b3b9251a1e8238f6", size = 1622410, upload-time = "2025-06-10T05:20:46.957Z" }, + { url = "https://files.pythonhosted.org/packages/17/54/8305f49a960376136ada977be1370fddb584c63d40bd1b9bef59469f28c7/aiohttp-3.12.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e408293aa910b0aea48b86a28eace41d497a85ba16c20f619f0c604597ef996c", size = 1675435, upload-time = "2025-06-10T05:20:49.379Z" }, + { url = "https://files.pythonhosted.org/packages/bb/dc/0a55350025bc297265cfa6c6b1b1f7508f4226ca3238697cbe5e772a7d76/aiohttp-3.12.12-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:f3d31faf290f5a30acba46b388465b67c6dbe8655d183e9efe2f6a1d594e6d9d", size = 1707099, upload-time = "2025-06-10T05:20:51.974Z" }, + { url = "https://files.pythonhosted.org/packages/d8/70/d949a1612b996e49d540c10ed77a0a1465c482a590e9a59c1c7897746119/aiohttp-3.12.12-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0b84731697325b023902aa643bd1726d999f5bc7854bc28b17ff410a81151d4b", size = 1649693, upload-time = "2025-06-10T05:20:54.973Z" }, + { url = "https://files.pythonhosted.org/packages/c1/ea/fb87beb7135e25576a1e6fbe98106c037d9fcf1543f19108f9ceb73c192c/aiohttp-3.12.12-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a324c6852b6e327811748446e56cc9bb6eaa58710557922183175816e82a4234", size = 1725825, upload-time = "2025-06-10T05:20:57.433Z" }, + { url = "https://files.pythonhosted.org/packages/f1/1f/adbeb3e440d49b733cef499ace94723ab1fe9fb516425e219379e03b7c9a/aiohttp-3.12.12-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:22fd867fbd72612dcf670c90486dbcbaf702cb807fb0b42bc0b7a142a573574a", size = 1759300, upload-time = "2025-06-10T05:21:00.444Z" }, + { url = "https://files.pythonhosted.org/packages/f2/c1/2fe007ad930f409d0d7fd9916cd55ec9b78b6a611a237424266ed71da48b/aiohttp-3.12.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3e092f1a970223794a4bf620a26c0e4e4e8e36bccae9b0b5da35e6d8ee598a03", size = 1708189, upload-time = "2025-06-10T05:21:02.969Z" }, + { url = "https://files.pythonhosted.org/packages/85/5e/ed3ed640fafae3972eae6cd26f66240108cf62452ac8128d59970d538cb1/aiohttp-3.12.12-cp313-cp313-win32.whl", hash = "sha256:7f5f5eb8717ef8ba15ab35fcde5a70ad28bbdc34157595d1cddd888a985f5aae", size = 420783, upload-time = "2025-06-10T05:21:06.287Z" }, + { url = "https://files.pythonhosted.org/packages/a6/db/57d2bb4af52dd0c6f62c42c7d34b82495b2902e50440134f70bfb7ee0fdd/aiohttp-3.12.12-cp313-cp313-win_amd64.whl", hash = "sha256:ace2499bdd03c329c054dc4b47361f2b19d5aa470f7db5c7e0e989336761b33c", size = 446721, upload-time = "2025-06-10T05:21:08.738Z" }, ] [[package]] @@ -104,18 +104,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "frozenlist" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ba/b5/6d55e80f6d8a08ce22b982eafa278d823b541c925f11ee774b0b9c43473d/aiosignal-1.3.2.tar.gz", hash = "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54", size = 19424 } +sdist = { url = "https://files.pythonhosted.org/packages/ba/b5/6d55e80f6d8a08ce22b982eafa278d823b541c925f11ee774b0b9c43473d/aiosignal-1.3.2.tar.gz", hash = "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54", size = 19424, upload-time = "2024-12-13T17:10:40.86Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/6a/bc7e17a3e87a2985d3e8f4da4cd0f481060eb78fb08596c42be62c90a4d9/aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5", size = 7597 }, + { url = "https://files.pythonhosted.org/packages/ec/6a/bc7e17a3e87a2985d3e8f4da4cd0f481060eb78fb08596c42be62c90a4d9/aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5", size = 7597, upload-time = "2024-12-13T17:10:38.469Z" }, ] [[package]] name = "annotated-types" version = "0.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 }, + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, ] [[package]] @@ -128,232 +128,232 @@ dependencies = [ { name = "sniffio" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949 } +sdist = { url = "https://files.pythonhosted.org/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949, upload-time = "2025-03-17T00:02:54.77Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916 }, + { url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916, upload-time = "2025-03-17T00:02:52.713Z" }, ] [[package]] name = "async-timeout" version = "5.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a5/ae/136395dfbfe00dfc94da3f3e136d0b13f394cba8f4841120e34226265780/async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3", size = 9274 } +sdist = { url = "https://files.pythonhosted.org/packages/a5/ae/136395dfbfe00dfc94da3f3e136d0b13f394cba8f4841120e34226265780/async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3", size = 9274, upload-time = "2024-11-06T16:41:39.6Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fe/ba/e2081de779ca30d473f21f5b30e0e737c438205440784c7dfc81efc2b029/async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c", size = 6233 }, + { url = "https://files.pythonhosted.org/packages/fe/ba/e2081de779ca30d473f21f5b30e0e737c438205440784c7dfc81efc2b029/async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c", size = 6233, upload-time = "2024-11-06T16:41:37.9Z" }, ] [[package]] name = "attrs" version = "25.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032 } +sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload-time = "2025-03-13T11:10:22.779Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815 }, + { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" }, ] [[package]] name = "bitarray" version = "3.4.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b8/0d/15826c7c2d49a4518a1b24b0d432f1ecad2e0b68168f942058b5de498498/bitarray-3.4.2.tar.gz", hash = "sha256:78ed2b911aabede3a31e3329b1de8abdc8104bd5e0545184ddbd9c7f668f4059", size = 143756 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f1/61/fa3a06d74bfba1dc591efa9f4f5ad2e5645f06a8c4d113cf12d18b5ac25b/bitarray-3.4.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:42b552f885c5629182928c79237b375a92bcf1bc1e725b1c8a5e8eab28ea300d", size = 141280 }, - { url = "https://files.pythonhosted.org/packages/17/ba/7eb30374c0e4c4b732a3ca3457d9fb0e44165ae4c5af9758597b03211a28/bitarray-3.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3e16d6184f349587b6a5045bcf073baf763a86273aab454485ba437d0bca82e8", size = 138031 }, - { url = "https://files.pythonhosted.org/packages/6e/6d/91582b0a232b54e910add5d0db34a926d0bdfdd1447685b8750349c71958/bitarray-3.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ecf456f0dee61bd818011e290d922e3e3b1aeb0544f6f19c4da9c5fc2e52818", size = 306437 }, - { url = "https://files.pythonhosted.org/packages/b8/23/113ccc20f6324d517ef6210c8fc6ae300346eb481c5a0483735e19b4deea/bitarray-3.4.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8bbe8249ae90dc0cd78b21d5d5d27a614e15bf30737ae6e8a0e2e60cc492acc", size = 322335 }, - { url = "https://files.pythonhosted.org/packages/6d/89/bf5a36e05ac3d77bdccbe9ba0eea4c47253411c2616379de0f181c27ecee/bitarray-3.4.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe7706f75f3b86e7afa516452bed9757ee301b59aea580c551c32a5e1cef082c", size = 314137 }, - { url = "https://files.pythonhosted.org/packages/66/a6/bed287f9095a2a266fc68ee42d6ee2815ff500783f973876d86a6d37a434/bitarray-3.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c60c8d30bb6efd2c04cf82d077df6449964234aeca996f6f1df317a08feffc0", size = 307963 }, - { url = "https://files.pythonhosted.org/packages/2f/50/3ca2adaf0da034e6c1a2ed60a3781b065672dd282e67f88593290c3990a7/bitarray-3.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b4cb5c22706d411010c7ce5efc0a4cc99f755a30fc7f6770eb1b1a0c0962bbb", size = 295182 }, - { url = "https://files.pythonhosted.org/packages/90/de/8c3d96e273bc51e4912185bd809fc6a9ec14a09e607336892c149e0c57c5/bitarray-3.4.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0fd60137a9474ce53bdace68c718a7c538f9df01d390452cc984f1ee78d7bcdb", size = 300063 }, - { url = "https://files.pythonhosted.org/packages/9d/71/34f0ea6ac5b2cbdd84f3e6283b5b796628cef616e786cb442cefce0fe224/bitarray-3.4.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:cd514a8e27d0751f0254861df60335edabacccfcb2457793ff30c8b2ed8f799d", size = 292053 }, - { url = "https://files.pythonhosted.org/packages/77/99/6ef41312536d2c37f14f0f7173aa1a012e9675d62900c10afa7641b47f75/bitarray-3.4.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:6c8f7447cdf2faff1d176c5dd207f0134f05cfa2a238d3d3944dc5019dc41593", size = 317007 }, - { url = "https://files.pythonhosted.org/packages/22/f9/cc4e73f54698bcdd1e0f1ea582da7e005464651e8116291a226deab95e1b/bitarray-3.4.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:75040a2a1abe4ccd40236f4ba0d39abde981d23f3ce7691b3b3f2137f134b99b", size = 319402 }, - { url = "https://files.pythonhosted.org/packages/55/40/c23dd5726107cbbc5e698b3fcca5ffac83d29146ef469f27f5277d18c2d7/bitarray-3.4.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ba15725cd9040b9b1b2650edb33253cb2ba7b68d087974e296e5ff082198952f", size = 299456 }, - { url = "https://files.pythonhosted.org/packages/21/31/6bfd9fda776f8d98512d5484fcb55fbb25e60796e7b5d3b9a3a300e8bc1c/bitarray-3.4.2-cp310-cp310-win32.whl", hash = "sha256:2959dfc61d963546e97220cfcaab7dfc489276c6e00092b57710522e68712b28", size = 134279 }, - { url = "https://files.pythonhosted.org/packages/82/9d/7067f6548b470beb86d83f7ac6c45cac3b9c28cf77fa0f9f3e67353d69d3/bitarray-3.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:97077fa0ec3b7eed57cd8d1cb0eb75d670423d20b7e4901482347a81efe2f6fd", size = 141360 }, - { url = "https://files.pythonhosted.org/packages/94/ba/508ba6a3ea16eb6c21baae33cd1b7bf6e299d21a496a1f90b8203a22d6d0/bitarray-3.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:90ca8e260b75a7ac0c542093e5f29154e51fd0d2d0fa5041c038cb2b58415eeb", size = 141425 }, - { url = "https://files.pythonhosted.org/packages/eb/a1/44d9b88cd3daee3734ea98dac691acc2c935a3bfbd5bfc38267a59bd986d/bitarray-3.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549dabcae78fb8f9133e3138b9473c7648d6054bb6fec84d28d3861aaec5ddd1", size = 138172 }, - { url = "https://files.pythonhosted.org/packages/5f/aa/5a8c33ab39e8a894978d42427ad0a1ba2d5c9cb61c8480101be555c0e3a7/bitarray-3.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a3da536ac84e6911cbc8e86be0baf1cab0d4f4ccb80c0f39b4fa28509f2db1a", size = 313373 }, - { url = "https://files.pythonhosted.org/packages/89/48/b0d28e21d91ec5c0477a320b9443096ddc816fbc59778b367f9e49094532/bitarray-3.4.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7a5e84d6b737de2d773ab1bd538e6f37fa7f667ea734f00a48d9a973b181c751", size = 329657 }, - { url = "https://files.pythonhosted.org/packages/bd/d5/1f858bd559568286435a460e7a169a5185b2b29184684e6c6fa303af3ca9/bitarray-3.4.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e265c5eede8316ba64bb6029832f282f6284a557b625bb3207a7680fd5da7925", size = 321873 }, - { url = "https://files.pythonhosted.org/packages/e8/c8/23df4174142cccf6a8bd114651b8e9bf965005ab1ef741d37c9f72e8d2eb/bitarray-3.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63fb45c60c7ab7a724aa64203305e56f344489e12d41619bdc9d7887d6562e01", size = 314796 }, - { url = "https://files.pythonhosted.org/packages/8f/21/329178b165f1aaf3f2ace3eb24aca5ad197febae908d7b41e552a69043e9/bitarray-3.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:083c2a9234dacf3e4e166a5844256da2a397941d3f6397e5b919bffca638f6ef", size = 302724 }, - { url = "https://files.pythonhosted.org/packages/26/a8/a66d3c0d3410d01f51824f8476b060f96b3353db7d6b45c87dba6d1aa0e0/bitarray-3.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e72606adb2438002873cb0e8e81c3fce926386a59bbafa82fea07cdb2a6d8a05", size = 307434 }, - { url = "https://files.pythonhosted.org/packages/ed/ac/3052386e7ff80c80eb2549a22c890f511e9f9f7fbbe6244b04255adae031/bitarray-3.4.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dc994d22a3a563e1d402dc2f64c61e60605a1a3e66dd8aea7636f607b99f03cb", size = 299232 }, - { url = "https://files.pythonhosted.org/packages/9d/46/91a32ccd39d40371ed7404d96a6f3cf1e381eaf36be5390c6bff5034f344/bitarray-3.4.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:214468391680ba1c831872a7949f1b563ab3cd832d10adc52df4f36e0af24446", size = 324056 }, - { url = "https://files.pythonhosted.org/packages/39/0e/cb824f0e0302cd08809f67b35b3ae21b47af5dd122e99740bfe6bde1c824/bitarray-3.4.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c7483b97807bb018a7cd7f9741800c714c9c56ba4e5a7e962c5f956c4b858f3c", size = 327058 }, - { url = "https://files.pythonhosted.org/packages/09/01/845e977d490e4e261179785540d1fdeff966c99296f503adc0e5407fc257/bitarray-3.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5774bf14ec451d5ac311cfcfe0b0cf2a1a9fa74b6ca81dfbc4f56a98872a5541", size = 306629 }, - { url = "https://files.pythonhosted.org/packages/29/ef/33ee8533ff1b2a8cd0b9e84fd81b2a90d66c2774544c861e281c5361eaa2/bitarray-3.4.2-cp311-cp311-win32.whl", hash = "sha256:e6f35567347ddb8b9e8b6bf6ab7d64be88bdb6b6c107b8edbb2c3d426c1590a0", size = 134450 }, - { url = "https://files.pythonhosted.org/packages/09/52/069c255d067319a9695c93369641d7f5539625069c1cf3ded2becff1bfbc/bitarray-3.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:ae5b0a8d3caf6284220232738dc7c05af81ec3a9f93d4a462295462dd0a492b2", size = 141596 }, - { url = "https://files.pythonhosted.org/packages/05/57/0b2b50eb3f50c3144f705d0994171f17fda00ee3a72d563ba764ea235f66/bitarray-3.4.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a0e498563e0eefa96a1b92461d083de11256f6510b7706d5f2e6473cd9b7137a", size = 141191 }, - { url = "https://files.pythonhosted.org/packages/81/c3/1d9ce4d0041c10ce90d924b8cea63afdda84a64623179045c0c67998922c/bitarray-3.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:114870ab71a0ebdac211aa0a120a54206c333b74b99fdf4b58fbe904979e1fef", size = 138158 }, - { url = "https://files.pythonhosted.org/packages/5d/dd/a8653dac671ba97b1c68ee73b08a0eb2042f24e5e31f51b86afc09588c06/bitarray-3.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fbf6121978cba4313c31f7cc5961e481242def2b8ddfea34ca27ba9da52c9c1", size = 315834 }, - { url = "https://files.pythonhosted.org/packages/3d/a2/30547bea0a35f9f953e99f5157749d56304d3f3a96b01a982dd604a9dc48/bitarray-3.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:423bb4e1bec0bc5d63969e12bcc5cc0081cc5aec4d7b62a6cd8240342aa36107", size = 331317 }, - { url = "https://files.pythonhosted.org/packages/2d/b9/1789476280f46455a9a30bcd252fda6fd995583d97d1b919ec0296393e2a/bitarray-3.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2ef80a96487c82477e8def69a58a218491794f7989b3e191cbaaa7b450315a5c", size = 324416 }, - { url = "https://files.pythonhosted.org/packages/84/89/519c829ca641a3e7b8c9be56d177aaa05572b7e15e4298df4a77959b6a1e/bitarray-3.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35f5c69a79047e50bc1d54a777541b0a86b213e23559b1ac3d76fa9a42cc5522", size = 317634 }, - { url = "https://files.pythonhosted.org/packages/0d/39/ebb6a6539261279c0994836b40b99384fa5e27ec239e70b203e310343f80/bitarray-3.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:002f7b128ed9d18d3ecb51ca78aeea5afffbe8e80d6be4ff2984d045b1c4b937", size = 305392 }, - { url = "https://files.pythonhosted.org/packages/83/04/0ee0d57b2a60fdf881346f196fd92b824f44f4736026da1d8c7970745266/bitarray-3.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:999bccc72704afcf4a3d9868db4d149c032cdf910f9f7d91e30166978530af7f", size = 309740 }, - { url = "https://files.pythonhosted.org/packages/f6/39/5ab0339e93097f2a2631ea281a6386c31707011499d5cf68b4e0e37ba124/bitarray-3.4.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2e44cfe2bc161cde3b11604f279e3048ef7bd3413837aadbd2ca30b5233c82cb", size = 301607 }, - { url = "https://files.pythonhosted.org/packages/e8/bb/b8f697ba6a16c1e393afe75029d069e2dd457e62b112c3cb26768d2e65eb/bitarray-3.4.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f408ba3e6f706a0eabae405d1906ceb539f34a318562a91ab9799c5e1712e18c", size = 325942 }, - { url = "https://files.pythonhosted.org/packages/64/ec/77d866a96909c09c5a34f1716f015386f9d9bbbf4b5dc7219f642b8043e2/bitarray-3.4.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:bf94513ae559b2525e6218e41b03790f866d75df5404490420f2c25e42cf55e7", size = 329491 }, - { url = "https://files.pythonhosted.org/packages/37/6e/633b7d392a39df655c92035da9ee52f7332bb165ae72038692a33a6def6c/bitarray-3.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6f2c88c792815d2755c49a3a1fca256e142c4adfadf1a2142b5a3a37e4d4b871", size = 309566 }, - { url = "https://files.pythonhosted.org/packages/ab/38/9d7ad6eca72e09b81097176dd66eed3aeaabdea4c24cf6ce25609599ce7b/bitarray-3.4.2-cp312-cp312-win32.whl", hash = "sha256:f4dac6b942c4d7ae5f6eb555ee3993de1432bf9c8f46e3caf74b6671ac5571a3", size = 134600 }, - { url = "https://files.pythonhosted.org/packages/d4/d3/c83ec3d912be73861a064f1a705436f270b8c5b5926350a875bd6c06b6df/bitarray-3.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:6c37e6814633041307f0df281651a86372b0ccdb1e4768247a87e83e2b68f9b9", size = 141844 }, - { url = "https://files.pythonhosted.org/packages/f2/22/973d377477e1f27cf64f9e3292343219577136e32665a52667589380100d/bitarray-3.4.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:16263bdbb05ce379e7b8e9a9f3e0a61a9204a06a037bbc91322d2939b3079fd5", size = 141162 }, - { url = "https://files.pythonhosted.org/packages/eb/53/65541b94fb6df1e8aa9a7359ac68f469c3243d8bc7302c5fb8ff8936dab2/bitarray-3.4.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:41fdc6fb8c3aabfcfe0073302c69fef0c74d6499491f133ba58755c3f2afb3d0", size = 138162 }, - { url = "https://files.pythonhosted.org/packages/a4/b2/83d587965f7969a5016a5bf5c9295a0651a34b668df41fa089d7c924ac08/bitarray-3.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02c2571337b11c69206e339170516f3e72b4ec16250876c4f2bbb6e82b9caa15", size = 315760 }, - { url = "https://files.pythonhosted.org/packages/4f/f5/2b2924181809debdb644143aa33d16facdce5763d5ff17e5301ecdaf89dc/bitarray-3.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c0e3d5f37217dde9b206418c37c4d86e173f072a892670e9714e6bb20b228e95", size = 331250 }, - { url = "https://files.pythonhosted.org/packages/00/2b/8ed4eeb947e05ef54614feff4cc4badd03e29ec35d46aa0218513cc9f8ac/bitarray-3.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:83202735f21fc781f27228daeae94b6c7df1a9f673b9dd6a1c0b3764d92b8e50", size = 324299 }, - { url = "https://files.pythonhosted.org/packages/05/27/d7f1b15c079cbeffad76f97c41c27635873be4d5600f6896b2bbc4f5caff/bitarray-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53b3f8c35812d85a299d6c0ff097f93e18dfb7a324c129e20a4ec0ecfc4ba995", size = 317522 }, - { url = "https://files.pythonhosted.org/packages/a5/db/e6a857a23222360dbc0b0d177e6060ecd88d63a1d6a3c2b52333c21a9683/bitarray-3.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef3f2e8ba5d6e0f38b57960d1bfb72aa9e2115f7cdca48561fadced652798d49", size = 305290 }, - { url = "https://files.pythonhosted.org/packages/16/12/3b945e415233889c57c26f95a9a6a245da546e2c8d1de09991332cb796ff/bitarray-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:508ec6547bdd9f0c435c322fbb127a3dfd74c943a6c7f77fa5dfcb3e9ce1de66", size = 309764 }, - { url = "https://files.pythonhosted.org/packages/6c/0e/9effb83e23ef5495c9078bdbac948df4fe2b202fb0ac5b33412848ab4b1e/bitarray-3.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1a3a08cc920f601258ea33d97b4454cd7cb04d17930e0a3bc7328ba3d732f8b0", size = 301690 }, - { url = "https://files.pythonhosted.org/packages/cb/67/9a73476c8cd6a67ff5ab9c5c1d916307e4fb9178d76ee2781552451c995c/bitarray-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:60189130ae1ebaadbab27e3ad0a7d7ed44f5d9456bbfae07c72138501ce59053", size = 326049 }, - { url = "https://files.pythonhosted.org/packages/bf/b1/2a81f5f96c1ccc033d8c63b4584aedbd9e27499cf2276fc70d4f87ad673b/bitarray-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:9e425eaf21a8d7b76531630029441c6d61f6064cbf4dd592af1607c79eb2e4d0", size = 329565 }, - { url = "https://files.pythonhosted.org/packages/2e/30/670efe7771944b4b7d0aacdc076969adc9428c9d0939ee70230bdf4c8aed/bitarray-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:952cc40c593f663ba083be76d1ccdb6dc9dafab8fb6d949056405636b2e720f3", size = 309661 }, - { url = "https://files.pythonhosted.org/packages/ee/2e/b2d8e842fe484d7d18fcd137289e396c7784b8484e0ec7e94ffe4bb7e8f9/bitarray-3.4.2-cp313-cp313-win32.whl", hash = "sha256:158f6b1a315eaf971f88e66f9b93431c3b580b46d2121c6a1166e7b761408fdf", size = 134614 }, - { url = "https://files.pythonhosted.org/packages/0c/50/0ec25a51197410a66146eea7950e3597baedb000f2f2e2458bb6d5306b0a/bitarray-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:2d24658ac96a82beb4da2f5c71bef9790f3dcabadbe8ead8dda742ab207fe2f9", size = 141851 }, - { url = "https://files.pythonhosted.org/packages/e7/03/77eca3d93f162c0982f370e6459d1fcb6ff51e84f80adb34c43256653bda/bitarray-3.4.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:9c02f3234b1ec391aa235b265a3649e8078d814cdd6b42bc5aee267cc370b0c8", size = 135778 }, - { url = "https://files.pythonhosted.org/packages/68/fd/5b148fb07e2b74e1cd17db7b940abdb1c7af6ac3a024810a5931db6e436b/bitarray-3.4.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:e19e5a35f53c0eaf4516cfa3f80de110eb831fd3d9785aa8b8f4a8a8c0d99523", size = 132826 }, - { url = "https://files.pythonhosted.org/packages/e5/50/8cfb459218cd074a3af7121f6509ac55be2d6ac5a0a048b188934976f589/bitarray-3.4.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f633d1e92fdc6a039b118d67f23d17b9ac4046a629bde04e178b770fe83a618f", size = 141592 }, - { url = "https://files.pythonhosted.org/packages/43/c0/a70a212ecfd4256e7281456beee5330945ea09cec8fb0be3f99ed6828a08/bitarray-3.4.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c08bc2ec3f15fbb3a99923ef1b16b621af45ab9d5146a06f970c0f0d7cab22ba", size = 142502 }, - { url = "https://files.pythonhosted.org/packages/1e/8e/9fc84001701ef1fd7f18b0254bf08d594adaed34fe0b5770d8c032b4d53a/bitarray-3.4.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eed46fa39af8440b1cff09a9805d65449583d524006efa29e5262bea9e08787e", size = 143930 }, - { url = "https://files.pythonhosted.org/packages/f7/05/2f6753d75282033e66e0a9626ef4209500cd7a08aa8f92cc70fa49681cf3/bitarray-3.4.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9cf23c13c84c1559ed28bd211a6290b7326c2011f6c30c82cee052b254ac09f0", size = 140275 }, +sdist = { url = "https://files.pythonhosted.org/packages/b8/0d/15826c7c2d49a4518a1b24b0d432f1ecad2e0b68168f942058b5de498498/bitarray-3.4.2.tar.gz", hash = "sha256:78ed2b911aabede3a31e3329b1de8abdc8104bd5e0545184ddbd9c7f668f4059", size = 143756, upload-time = "2025-05-21T16:21:44.056Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/61/fa3a06d74bfba1dc591efa9f4f5ad2e5645f06a8c4d113cf12d18b5ac25b/bitarray-3.4.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:42b552f885c5629182928c79237b375a92bcf1bc1e725b1c8a5e8eab28ea300d", size = 141280, upload-time = "2025-05-21T16:18:02.593Z" }, + { url = "https://files.pythonhosted.org/packages/17/ba/7eb30374c0e4c4b732a3ca3457d9fb0e44165ae4c5af9758597b03211a28/bitarray-3.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3e16d6184f349587b6a5045bcf073baf763a86273aab454485ba437d0bca82e8", size = 138031, upload-time = "2025-05-21T16:18:05.616Z" }, + { url = "https://files.pythonhosted.org/packages/6e/6d/91582b0a232b54e910add5d0db34a926d0bdfdd1447685b8750349c71958/bitarray-3.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ecf456f0dee61bd818011e290d922e3e3b1aeb0544f6f19c4da9c5fc2e52818", size = 306437, upload-time = "2025-05-21T16:18:06.793Z" }, + { url = "https://files.pythonhosted.org/packages/b8/23/113ccc20f6324d517ef6210c8fc6ae300346eb481c5a0483735e19b4deea/bitarray-3.4.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8bbe8249ae90dc0cd78b21d5d5d27a614e15bf30737ae6e8a0e2e60cc492acc", size = 322335, upload-time = "2025-05-21T16:18:07.925Z" }, + { url = "https://files.pythonhosted.org/packages/6d/89/bf5a36e05ac3d77bdccbe9ba0eea4c47253411c2616379de0f181c27ecee/bitarray-3.4.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe7706f75f3b86e7afa516452bed9757ee301b59aea580c551c32a5e1cef082c", size = 314137, upload-time = "2025-05-21T16:18:09.333Z" }, + { url = "https://files.pythonhosted.org/packages/66/a6/bed287f9095a2a266fc68ee42d6ee2815ff500783f973876d86a6d37a434/bitarray-3.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c60c8d30bb6efd2c04cf82d077df6449964234aeca996f6f1df317a08feffc0", size = 307963, upload-time = "2025-05-21T16:18:10.618Z" }, + { url = "https://files.pythonhosted.org/packages/2f/50/3ca2adaf0da034e6c1a2ed60a3781b065672dd282e67f88593290c3990a7/bitarray-3.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b4cb5c22706d411010c7ce5efc0a4cc99f755a30fc7f6770eb1b1a0c0962bbb", size = 295182, upload-time = "2025-05-21T16:18:11.932Z" }, + { url = "https://files.pythonhosted.org/packages/90/de/8c3d96e273bc51e4912185bd809fc6a9ec14a09e607336892c149e0c57c5/bitarray-3.4.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0fd60137a9474ce53bdace68c718a7c538f9df01d390452cc984f1ee78d7bcdb", size = 300063, upload-time = "2025-05-21T16:18:13.221Z" }, + { url = "https://files.pythonhosted.org/packages/9d/71/34f0ea6ac5b2cbdd84f3e6283b5b796628cef616e786cb442cefce0fe224/bitarray-3.4.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:cd514a8e27d0751f0254861df60335edabacccfcb2457793ff30c8b2ed8f799d", size = 292053, upload-time = "2025-05-21T16:18:14.802Z" }, + { url = "https://files.pythonhosted.org/packages/77/99/6ef41312536d2c37f14f0f7173aa1a012e9675d62900c10afa7641b47f75/bitarray-3.4.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:6c8f7447cdf2faff1d176c5dd207f0134f05cfa2a238d3d3944dc5019dc41593", size = 317007, upload-time = "2025-05-21T16:18:16.117Z" }, + { url = "https://files.pythonhosted.org/packages/22/f9/cc4e73f54698bcdd1e0f1ea582da7e005464651e8116291a226deab95e1b/bitarray-3.4.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:75040a2a1abe4ccd40236f4ba0d39abde981d23f3ce7691b3b3f2137f134b99b", size = 319402, upload-time = "2025-05-21T16:18:18.097Z" }, + { url = "https://files.pythonhosted.org/packages/55/40/c23dd5726107cbbc5e698b3fcca5ffac83d29146ef469f27f5277d18c2d7/bitarray-3.4.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ba15725cd9040b9b1b2650edb33253cb2ba7b68d087974e296e5ff082198952f", size = 299456, upload-time = "2025-05-21T16:18:20.029Z" }, + { url = "https://files.pythonhosted.org/packages/21/31/6bfd9fda776f8d98512d5484fcb55fbb25e60796e7b5d3b9a3a300e8bc1c/bitarray-3.4.2-cp310-cp310-win32.whl", hash = "sha256:2959dfc61d963546e97220cfcaab7dfc489276c6e00092b57710522e68712b28", size = 134279, upload-time = "2025-05-21T16:18:21.609Z" }, + { url = "https://files.pythonhosted.org/packages/82/9d/7067f6548b470beb86d83f7ac6c45cac3b9c28cf77fa0f9f3e67353d69d3/bitarray-3.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:97077fa0ec3b7eed57cd8d1cb0eb75d670423d20b7e4901482347a81efe2f6fd", size = 141360, upload-time = "2025-05-21T16:18:23.197Z" }, + { url = "https://files.pythonhosted.org/packages/94/ba/508ba6a3ea16eb6c21baae33cd1b7bf6e299d21a496a1f90b8203a22d6d0/bitarray-3.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:90ca8e260b75a7ac0c542093e5f29154e51fd0d2d0fa5041c038cb2b58415eeb", size = 141425, upload-time = "2025-05-21T16:18:24.452Z" }, + { url = "https://files.pythonhosted.org/packages/eb/a1/44d9b88cd3daee3734ea98dac691acc2c935a3bfbd5bfc38267a59bd986d/bitarray-3.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549dabcae78fb8f9133e3138b9473c7648d6054bb6fec84d28d3861aaec5ddd1", size = 138172, upload-time = "2025-05-21T16:18:25.601Z" }, + { url = "https://files.pythonhosted.org/packages/5f/aa/5a8c33ab39e8a894978d42427ad0a1ba2d5c9cb61c8480101be555c0e3a7/bitarray-3.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a3da536ac84e6911cbc8e86be0baf1cab0d4f4ccb80c0f39b4fa28509f2db1a", size = 313373, upload-time = "2025-05-21T16:18:26.796Z" }, + { url = "https://files.pythonhosted.org/packages/89/48/b0d28e21d91ec5c0477a320b9443096ddc816fbc59778b367f9e49094532/bitarray-3.4.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7a5e84d6b737de2d773ab1bd538e6f37fa7f667ea734f00a48d9a973b181c751", size = 329657, upload-time = "2025-05-21T16:18:28.097Z" }, + { url = "https://files.pythonhosted.org/packages/bd/d5/1f858bd559568286435a460e7a169a5185b2b29184684e6c6fa303af3ca9/bitarray-3.4.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e265c5eede8316ba64bb6029832f282f6284a557b625bb3207a7680fd5da7925", size = 321873, upload-time = "2025-05-21T16:18:29.511Z" }, + { url = "https://files.pythonhosted.org/packages/e8/c8/23df4174142cccf6a8bd114651b8e9bf965005ab1ef741d37c9f72e8d2eb/bitarray-3.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63fb45c60c7ab7a724aa64203305e56f344489e12d41619bdc9d7887d6562e01", size = 314796, upload-time = "2025-05-21T16:18:31.2Z" }, + { url = "https://files.pythonhosted.org/packages/8f/21/329178b165f1aaf3f2ace3eb24aca5ad197febae908d7b41e552a69043e9/bitarray-3.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:083c2a9234dacf3e4e166a5844256da2a397941d3f6397e5b919bffca638f6ef", size = 302724, upload-time = "2025-05-21T16:18:32.729Z" }, + { url = "https://files.pythonhosted.org/packages/26/a8/a66d3c0d3410d01f51824f8476b060f96b3353db7d6b45c87dba6d1aa0e0/bitarray-3.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e72606adb2438002873cb0e8e81c3fce926386a59bbafa82fea07cdb2a6d8a05", size = 307434, upload-time = "2025-05-21T16:18:34.394Z" }, + { url = "https://files.pythonhosted.org/packages/ed/ac/3052386e7ff80c80eb2549a22c890f511e9f9f7fbbe6244b04255adae031/bitarray-3.4.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dc994d22a3a563e1d402dc2f64c61e60605a1a3e66dd8aea7636f607b99f03cb", size = 299232, upload-time = "2025-05-21T16:18:35.708Z" }, + { url = "https://files.pythonhosted.org/packages/9d/46/91a32ccd39d40371ed7404d96a6f3cf1e381eaf36be5390c6bff5034f344/bitarray-3.4.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:214468391680ba1c831872a7949f1b563ab3cd832d10adc52df4f36e0af24446", size = 324056, upload-time = "2025-05-21T16:18:37.536Z" }, + { url = "https://files.pythonhosted.org/packages/39/0e/cb824f0e0302cd08809f67b35b3ae21b47af5dd122e99740bfe6bde1c824/bitarray-3.4.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c7483b97807bb018a7cd7f9741800c714c9c56ba4e5a7e962c5f956c4b858f3c", size = 327058, upload-time = "2025-05-21T16:18:38.856Z" }, + { url = "https://files.pythonhosted.org/packages/09/01/845e977d490e4e261179785540d1fdeff966c99296f503adc0e5407fc257/bitarray-3.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5774bf14ec451d5ac311cfcfe0b0cf2a1a9fa74b6ca81dfbc4f56a98872a5541", size = 306629, upload-time = "2025-05-21T16:18:40.211Z" }, + { url = "https://files.pythonhosted.org/packages/29/ef/33ee8533ff1b2a8cd0b9e84fd81b2a90d66c2774544c861e281c5361eaa2/bitarray-3.4.2-cp311-cp311-win32.whl", hash = "sha256:e6f35567347ddb8b9e8b6bf6ab7d64be88bdb6b6c107b8edbb2c3d426c1590a0", size = 134450, upload-time = "2025-05-21T16:18:42.435Z" }, + { url = "https://files.pythonhosted.org/packages/09/52/069c255d067319a9695c93369641d7f5539625069c1cf3ded2becff1bfbc/bitarray-3.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:ae5b0a8d3caf6284220232738dc7c05af81ec3a9f93d4a462295462dd0a492b2", size = 141596, upload-time = "2025-05-21T16:18:43.743Z" }, + { url = "https://files.pythonhosted.org/packages/05/57/0b2b50eb3f50c3144f705d0994171f17fda00ee3a72d563ba764ea235f66/bitarray-3.4.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a0e498563e0eefa96a1b92461d083de11256f6510b7706d5f2e6473cd9b7137a", size = 141191, upload-time = "2025-05-21T16:18:45.436Z" }, + { url = "https://files.pythonhosted.org/packages/81/c3/1d9ce4d0041c10ce90d924b8cea63afdda84a64623179045c0c67998922c/bitarray-3.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:114870ab71a0ebdac211aa0a120a54206c333b74b99fdf4b58fbe904979e1fef", size = 138158, upload-time = "2025-05-21T16:18:46.685Z" }, + { url = "https://files.pythonhosted.org/packages/5d/dd/a8653dac671ba97b1c68ee73b08a0eb2042f24e5e31f51b86afc09588c06/bitarray-3.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fbf6121978cba4313c31f7cc5961e481242def2b8ddfea34ca27ba9da52c9c1", size = 315834, upload-time = "2025-05-21T16:18:47.926Z" }, + { url = "https://files.pythonhosted.org/packages/3d/a2/30547bea0a35f9f953e99f5157749d56304d3f3a96b01a982dd604a9dc48/bitarray-3.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:423bb4e1bec0bc5d63969e12bcc5cc0081cc5aec4d7b62a6cd8240342aa36107", size = 331317, upload-time = "2025-05-21T16:18:49.169Z" }, + { url = "https://files.pythonhosted.org/packages/2d/b9/1789476280f46455a9a30bcd252fda6fd995583d97d1b919ec0296393e2a/bitarray-3.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2ef80a96487c82477e8def69a58a218491794f7989b3e191cbaaa7b450315a5c", size = 324416, upload-time = "2025-05-21T16:18:50.917Z" }, + { url = "https://files.pythonhosted.org/packages/84/89/519c829ca641a3e7b8c9be56d177aaa05572b7e15e4298df4a77959b6a1e/bitarray-3.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35f5c69a79047e50bc1d54a777541b0a86b213e23559b1ac3d76fa9a42cc5522", size = 317634, upload-time = "2025-05-21T16:18:52.718Z" }, + { url = "https://files.pythonhosted.org/packages/0d/39/ebb6a6539261279c0994836b40b99384fa5e27ec239e70b203e310343f80/bitarray-3.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:002f7b128ed9d18d3ecb51ca78aeea5afffbe8e80d6be4ff2984d045b1c4b937", size = 305392, upload-time = "2025-05-21T16:18:54.888Z" }, + { url = "https://files.pythonhosted.org/packages/83/04/0ee0d57b2a60fdf881346f196fd92b824f44f4736026da1d8c7970745266/bitarray-3.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:999bccc72704afcf4a3d9868db4d149c032cdf910f9f7d91e30166978530af7f", size = 309740, upload-time = "2025-05-21T16:18:56.76Z" }, + { url = "https://files.pythonhosted.org/packages/f6/39/5ab0339e93097f2a2631ea281a6386c31707011499d5cf68b4e0e37ba124/bitarray-3.4.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2e44cfe2bc161cde3b11604f279e3048ef7bd3413837aadbd2ca30b5233c82cb", size = 301607, upload-time = "2025-05-21T16:18:58.144Z" }, + { url = "https://files.pythonhosted.org/packages/e8/bb/b8f697ba6a16c1e393afe75029d069e2dd457e62b112c3cb26768d2e65eb/bitarray-3.4.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f408ba3e6f706a0eabae405d1906ceb539f34a318562a91ab9799c5e1712e18c", size = 325942, upload-time = "2025-05-21T16:18:59.471Z" }, + { url = "https://files.pythonhosted.org/packages/64/ec/77d866a96909c09c5a34f1716f015386f9d9bbbf4b5dc7219f642b8043e2/bitarray-3.4.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:bf94513ae559b2525e6218e41b03790f866d75df5404490420f2c25e42cf55e7", size = 329491, upload-time = "2025-05-21T16:19:01.205Z" }, + { url = "https://files.pythonhosted.org/packages/37/6e/633b7d392a39df655c92035da9ee52f7332bb165ae72038692a33a6def6c/bitarray-3.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6f2c88c792815d2755c49a3a1fca256e142c4adfadf1a2142b5a3a37e4d4b871", size = 309566, upload-time = "2025-05-21T16:19:02.762Z" }, + { url = "https://files.pythonhosted.org/packages/ab/38/9d7ad6eca72e09b81097176dd66eed3aeaabdea4c24cf6ce25609599ce7b/bitarray-3.4.2-cp312-cp312-win32.whl", hash = "sha256:f4dac6b942c4d7ae5f6eb555ee3993de1432bf9c8f46e3caf74b6671ac5571a3", size = 134600, upload-time = "2025-05-21T16:19:04.057Z" }, + { url = "https://files.pythonhosted.org/packages/d4/d3/c83ec3d912be73861a064f1a705436f270b8c5b5926350a875bd6c06b6df/bitarray-3.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:6c37e6814633041307f0df281651a86372b0ccdb1e4768247a87e83e2b68f9b9", size = 141844, upload-time = "2025-05-21T16:19:05.254Z" }, + { url = "https://files.pythonhosted.org/packages/f2/22/973d377477e1f27cf64f9e3292343219577136e32665a52667589380100d/bitarray-3.4.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:16263bdbb05ce379e7b8e9a9f3e0a61a9204a06a037bbc91322d2939b3079fd5", size = 141162, upload-time = "2025-05-21T16:19:06.488Z" }, + { url = "https://files.pythonhosted.org/packages/eb/53/65541b94fb6df1e8aa9a7359ac68f469c3243d8bc7302c5fb8ff8936dab2/bitarray-3.4.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:41fdc6fb8c3aabfcfe0073302c69fef0c74d6499491f133ba58755c3f2afb3d0", size = 138162, upload-time = "2025-05-21T16:19:07.688Z" }, + { url = "https://files.pythonhosted.org/packages/a4/b2/83d587965f7969a5016a5bf5c9295a0651a34b668df41fa089d7c924ac08/bitarray-3.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02c2571337b11c69206e339170516f3e72b4ec16250876c4f2bbb6e82b9caa15", size = 315760, upload-time = "2025-05-21T16:19:09.834Z" }, + { url = "https://files.pythonhosted.org/packages/4f/f5/2b2924181809debdb644143aa33d16facdce5763d5ff17e5301ecdaf89dc/bitarray-3.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c0e3d5f37217dde9b206418c37c4d86e173f072a892670e9714e6bb20b228e95", size = 331250, upload-time = "2025-05-21T16:19:11.449Z" }, + { url = "https://files.pythonhosted.org/packages/00/2b/8ed4eeb947e05ef54614feff4cc4badd03e29ec35d46aa0218513cc9f8ac/bitarray-3.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:83202735f21fc781f27228daeae94b6c7df1a9f673b9dd6a1c0b3764d92b8e50", size = 324299, upload-time = "2025-05-21T16:19:13.236Z" }, + { url = "https://files.pythonhosted.org/packages/05/27/d7f1b15c079cbeffad76f97c41c27635873be4d5600f6896b2bbc4f5caff/bitarray-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53b3f8c35812d85a299d6c0ff097f93e18dfb7a324c129e20a4ec0ecfc4ba995", size = 317522, upload-time = "2025-05-21T16:19:14.832Z" }, + { url = "https://files.pythonhosted.org/packages/a5/db/e6a857a23222360dbc0b0d177e6060ecd88d63a1d6a3c2b52333c21a9683/bitarray-3.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef3f2e8ba5d6e0f38b57960d1bfb72aa9e2115f7cdca48561fadced652798d49", size = 305290, upload-time = "2025-05-21T16:19:16.57Z" }, + { url = "https://files.pythonhosted.org/packages/16/12/3b945e415233889c57c26f95a9a6a245da546e2c8d1de09991332cb796ff/bitarray-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:508ec6547bdd9f0c435c322fbb127a3dfd74c943a6c7f77fa5dfcb3e9ce1de66", size = 309764, upload-time = "2025-05-21T16:19:18.34Z" }, + { url = "https://files.pythonhosted.org/packages/6c/0e/9effb83e23ef5495c9078bdbac948df4fe2b202fb0ac5b33412848ab4b1e/bitarray-3.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1a3a08cc920f601258ea33d97b4454cd7cb04d17930e0a3bc7328ba3d732f8b0", size = 301690, upload-time = "2025-05-21T16:19:19.694Z" }, + { url = "https://files.pythonhosted.org/packages/cb/67/9a73476c8cd6a67ff5ab9c5c1d916307e4fb9178d76ee2781552451c995c/bitarray-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:60189130ae1ebaadbab27e3ad0a7d7ed44f5d9456bbfae07c72138501ce59053", size = 326049, upload-time = "2025-05-21T16:19:21.371Z" }, + { url = "https://files.pythonhosted.org/packages/bf/b1/2a81f5f96c1ccc033d8c63b4584aedbd9e27499cf2276fc70d4f87ad673b/bitarray-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:9e425eaf21a8d7b76531630029441c6d61f6064cbf4dd592af1607c79eb2e4d0", size = 329565, upload-time = "2025-05-21T16:19:22.88Z" }, + { url = "https://files.pythonhosted.org/packages/2e/30/670efe7771944b4b7d0aacdc076969adc9428c9d0939ee70230bdf4c8aed/bitarray-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:952cc40c593f663ba083be76d1ccdb6dc9dafab8fb6d949056405636b2e720f3", size = 309661, upload-time = "2025-05-21T16:19:24.574Z" }, + { url = "https://files.pythonhosted.org/packages/ee/2e/b2d8e842fe484d7d18fcd137289e396c7784b8484e0ec7e94ffe4bb7e8f9/bitarray-3.4.2-cp313-cp313-win32.whl", hash = "sha256:158f6b1a315eaf971f88e66f9b93431c3b580b46d2121c6a1166e7b761408fdf", size = 134614, upload-time = "2025-05-21T16:19:25.914Z" }, + { url = "https://files.pythonhosted.org/packages/0c/50/0ec25a51197410a66146eea7950e3597baedb000f2f2e2458bb6d5306b0a/bitarray-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:2d24658ac96a82beb4da2f5c71bef9790f3dcabadbe8ead8dda742ab207fe2f9", size = 141851, upload-time = "2025-05-21T16:19:27.388Z" }, + { url = "https://files.pythonhosted.org/packages/e7/03/77eca3d93f162c0982f370e6459d1fcb6ff51e84f80adb34c43256653bda/bitarray-3.4.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:9c02f3234b1ec391aa235b265a3649e8078d814cdd6b42bc5aee267cc370b0c8", size = 135778, upload-time = "2025-05-21T16:20:58.492Z" }, + { url = "https://files.pythonhosted.org/packages/68/fd/5b148fb07e2b74e1cd17db7b940abdb1c7af6ac3a024810a5931db6e436b/bitarray-3.4.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:e19e5a35f53c0eaf4516cfa3f80de110eb831fd3d9785aa8b8f4a8a8c0d99523", size = 132826, upload-time = "2025-05-21T16:21:00.901Z" }, + { url = "https://files.pythonhosted.org/packages/e5/50/8cfb459218cd074a3af7121f6509ac55be2d6ac5a0a048b188934976f589/bitarray-3.4.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f633d1e92fdc6a039b118d67f23d17b9ac4046a629bde04e178b770fe83a618f", size = 141592, upload-time = "2025-05-21T16:21:02.4Z" }, + { url = "https://files.pythonhosted.org/packages/43/c0/a70a212ecfd4256e7281456beee5330945ea09cec8fb0be3f99ed6828a08/bitarray-3.4.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c08bc2ec3f15fbb3a99923ef1b16b621af45ab9d5146a06f970c0f0d7cab22ba", size = 142502, upload-time = "2025-05-21T16:21:08.366Z" }, + { url = "https://files.pythonhosted.org/packages/1e/8e/9fc84001701ef1fd7f18b0254bf08d594adaed34fe0b5770d8c032b4d53a/bitarray-3.4.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eed46fa39af8440b1cff09a9805d65449583d524006efa29e5262bea9e08787e", size = 143930, upload-time = "2025-05-21T16:21:09.819Z" }, + { url = "https://files.pythonhosted.org/packages/f7/05/2f6753d75282033e66e0a9626ef4209500cd7a08aa8f92cc70fa49681cf3/bitarray-3.4.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9cf23c13c84c1559ed28bd211a6290b7326c2011f6c30c82cee052b254ac09f0", size = 140275, upload-time = "2025-05-21T16:21:11.481Z" }, ] [[package]] name = "blinker" version = "1.9.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/21/28/9b3f50ce0e048515135495f198351908d99540d69bfdc8c1d15b73dc55ce/blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf", size = 22460 } +sdist = { url = "https://files.pythonhosted.org/packages/21/28/9b3f50ce0e048515135495f198351908d99540d69bfdc8c1d15b73dc55ce/blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf", size = 22460, upload-time = "2024-11-08T17:25:47.436Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc", size = 8458 }, + { url = "https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc", size = 8458, upload-time = "2024-11-08T17:25:46.184Z" }, ] [[package]] name = "certifi" version = "2025.4.26" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705 } +sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705, upload-time = "2025-04-26T02:12:29.51Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618 }, + { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618, upload-time = "2025-04-26T02:12:27.662Z" }, ] [[package]] name = "charset-normalizer" version = "3.4.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e4/33/89c2ced2b67d1c2a61c19c6751aa8902d46ce3dacb23600a283619f5a12d/charset_normalizer-3.4.2.tar.gz", hash = "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63", size = 126367 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/95/28/9901804da60055b406e1a1c5ba7aac1276fb77f1dde635aabfc7fd84b8ab/charset_normalizer-3.4.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c48ed483eb946e6c04ccbe02c6b4d1d48e51944b6db70f697e089c193404941", size = 201818 }, - { url = "https://files.pythonhosted.org/packages/d9/9b/892a8c8af9110935e5adcbb06d9c6fe741b6bb02608c6513983048ba1a18/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2d318c11350e10662026ad0eb71bb51c7812fc8590825304ae0bdd4ac283acd", size = 144649 }, - { url = "https://files.pythonhosted.org/packages/7b/a5/4179abd063ff6414223575e008593861d62abfc22455b5d1a44995b7c101/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9cbfacf36cb0ec2897ce0ebc5d08ca44213af24265bd56eca54bee7923c48fd6", size = 155045 }, - { url = "https://files.pythonhosted.org/packages/3b/95/bc08c7dfeddd26b4be8c8287b9bb055716f31077c8b0ea1cd09553794665/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18dd2e350387c87dabe711b86f83c9c78af772c748904d372ade190b5c7c9d4d", size = 147356 }, - { url = "https://files.pythonhosted.org/packages/a8/2d/7a5b635aa65284bf3eab7653e8b4151ab420ecbae918d3e359d1947b4d61/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8075c35cd58273fee266c58c0c9b670947c19df5fb98e7b66710e04ad4e9ff86", size = 149471 }, - { url = "https://files.pythonhosted.org/packages/ae/38/51fc6ac74251fd331a8cfdb7ec57beba8c23fd5493f1050f71c87ef77ed0/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5bf4545e3b962767e5c06fe1738f951f77d27967cb2caa64c28be7c4563e162c", size = 151317 }, - { url = "https://files.pythonhosted.org/packages/b7/17/edee1e32215ee6e9e46c3e482645b46575a44a2d72c7dfd49e49f60ce6bf/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a6ab32f7210554a96cd9e33abe3ddd86732beeafc7a28e9955cdf22ffadbab0", size = 146368 }, - { url = "https://files.pythonhosted.org/packages/26/2c/ea3e66f2b5f21fd00b2825c94cafb8c326ea6240cd80a91eb09e4a285830/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b33de11b92e9f75a2b545d6e9b6f37e398d86c3e9e9653c4864eb7e89c5773ef", size = 154491 }, - { url = "https://files.pythonhosted.org/packages/52/47/7be7fa972422ad062e909fd62460d45c3ef4c141805b7078dbab15904ff7/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8755483f3c00d6c9a77f490c17e6ab0c8729e39e6390328e42521ef175380ae6", size = 157695 }, - { url = "https://files.pythonhosted.org/packages/2f/42/9f02c194da282b2b340f28e5fb60762de1151387a36842a92b533685c61e/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:68a328e5f55ec37c57f19ebb1fdc56a248db2e3e9ad769919a58672958e8f366", size = 154849 }, - { url = "https://files.pythonhosted.org/packages/67/44/89cacd6628f31fb0b63201a618049be4be2a7435a31b55b5eb1c3674547a/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:21b2899062867b0e1fde9b724f8aecb1af14f2778d69aacd1a5a1853a597a5db", size = 150091 }, - { url = "https://files.pythonhosted.org/packages/1f/79/4b8da9f712bc079c0f16b6d67b099b0b8d808c2292c937f267d816ec5ecc/charset_normalizer-3.4.2-cp310-cp310-win32.whl", hash = "sha256:e8082b26888e2f8b36a042a58307d5b917ef2b1cacab921ad3323ef91901c71a", size = 98445 }, - { url = "https://files.pythonhosted.org/packages/7d/d7/96970afb4fb66497a40761cdf7bd4f6fca0fc7bafde3a84f836c1f57a926/charset_normalizer-3.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:f69a27e45c43520f5487f27627059b64aaf160415589230992cec34c5e18a509", size = 105782 }, - { url = "https://files.pythonhosted.org/packages/05/85/4c40d00dcc6284a1c1ad5de5e0996b06f39d8232f1031cd23c2f5c07ee86/charset_normalizer-3.4.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:be1e352acbe3c78727a16a455126d9ff83ea2dfdcbc83148d2982305a04714c2", size = 198794 }, - { url = "https://files.pythonhosted.org/packages/41/d9/7a6c0b9db952598e97e93cbdfcb91bacd89b9b88c7c983250a77c008703c/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa88ca0b1932e93f2d961bf3addbb2db902198dca337d88c89e1559e066e7645", size = 142846 }, - { url = "https://files.pythonhosted.org/packages/66/82/a37989cda2ace7e37f36c1a8ed16c58cf48965a79c2142713244bf945c89/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d524ba3f1581b35c03cb42beebab4a13e6cdad7b36246bd22541fa585a56cccd", size = 153350 }, - { url = "https://files.pythonhosted.org/packages/df/68/a576b31b694d07b53807269d05ec3f6f1093e9545e8607121995ba7a8313/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28a1005facc94196e1fb3e82a3d442a9d9110b8434fc1ded7a24a2983c9888d8", size = 145657 }, - { url = "https://files.pythonhosted.org/packages/92/9b/ad67f03d74554bed3aefd56fe836e1623a50780f7c998d00ca128924a499/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdb20a30fe1175ecabed17cbf7812f7b804b8a315a25f24678bcdf120a90077f", size = 147260 }, - { url = "https://files.pythonhosted.org/packages/a6/e6/8aebae25e328160b20e31a7e9929b1578bbdc7f42e66f46595a432f8539e/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f5d9ed7f254402c9e7d35d2f5972c9bbea9040e99cd2861bd77dc68263277c7", size = 149164 }, - { url = "https://files.pythonhosted.org/packages/8b/f2/b3c2f07dbcc248805f10e67a0262c93308cfa149a4cd3d1fe01f593e5fd2/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:efd387a49825780ff861998cd959767800d54f8308936b21025326de4b5a42b9", size = 144571 }, - { url = "https://files.pythonhosted.org/packages/60/5b/c3f3a94bc345bc211622ea59b4bed9ae63c00920e2e8f11824aa5708e8b7/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f0aa37f3c979cf2546b73e8222bbfa3dc07a641585340179d768068e3455e544", size = 151952 }, - { url = "https://files.pythonhosted.org/packages/e2/4d/ff460c8b474122334c2fa394a3f99a04cf11c646da895f81402ae54f5c42/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e70e990b2137b29dc5564715de1e12701815dacc1d056308e2b17e9095372a82", size = 155959 }, - { url = "https://files.pythonhosted.org/packages/a2/2b/b964c6a2fda88611a1fe3d4c400d39c66a42d6c169c924818c848f922415/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0c8c57f84ccfc871a48a47321cfa49ae1df56cd1d965a09abe84066f6853b9c0", size = 153030 }, - { url = "https://files.pythonhosted.org/packages/59/2e/d3b9811db26a5ebf444bc0fa4f4be5aa6d76fc6e1c0fd537b16c14e849b6/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6b66f92b17849b85cad91259efc341dce9c1af48e2173bf38a85c6329f1033e5", size = 148015 }, - { url = "https://files.pythonhosted.org/packages/90/07/c5fd7c11eafd561bb51220d600a788f1c8d77c5eef37ee49454cc5c35575/charset_normalizer-3.4.2-cp311-cp311-win32.whl", hash = "sha256:daac4765328a919a805fa5e2720f3e94767abd632ae410a9062dff5412bae65a", size = 98106 }, - { url = "https://files.pythonhosted.org/packages/a8/05/5e33dbef7e2f773d672b6d79f10ec633d4a71cd96db6673625838a4fd532/charset_normalizer-3.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53efc7c7cee4c1e70661e2e112ca46a575f90ed9ae3fef200f2a25e954f4b28", size = 105402 }, - { url = "https://files.pythonhosted.org/packages/d7/a4/37f4d6035c89cac7930395a35cc0f1b872e652eaafb76a6075943754f095/charset_normalizer-3.4.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0c29de6a1a95f24b9a1aa7aefd27d2487263f00dfd55a77719b530788f75cff7", size = 199936 }, - { url = "https://files.pythonhosted.org/packages/ee/8a/1a5e33b73e0d9287274f899d967907cd0bf9c343e651755d9307e0dbf2b3/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cddf7bd982eaa998934a91f69d182aec997c6c468898efe6679af88283b498d3", size = 143790 }, - { url = "https://files.pythonhosted.org/packages/66/52/59521f1d8e6ab1482164fa21409c5ef44da3e9f653c13ba71becdd98dec3/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a", size = 153924 }, - { url = "https://files.pythonhosted.org/packages/86/2d/fb55fdf41964ec782febbf33cb64be480a6b8f16ded2dbe8db27a405c09f/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d41c4d287cfc69060fa91cae9683eacffad989f1a10811995fa309df656ec214", size = 146626 }, - { url = "https://files.pythonhosted.org/packages/8c/73/6ede2ec59bce19b3edf4209d70004253ec5f4e319f9a2e3f2f15601ed5f7/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a", size = 148567 }, - { url = "https://files.pythonhosted.org/packages/09/14/957d03c6dc343c04904530b6bef4e5efae5ec7d7990a7cbb868e4595ee30/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf713fe9a71ef6fd5adf7a79670135081cd4431c2943864757f0fa3a65b1fafd", size = 150957 }, - { url = "https://files.pythonhosted.org/packages/0d/c8/8174d0e5c10ccebdcb1b53cc959591c4c722a3ad92461a273e86b9f5a302/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a370b3e078e418187da8c3674eddb9d983ec09445c99a3a263c2011993522981", size = 145408 }, - { url = "https://files.pythonhosted.org/packages/58/aa/8904b84bc8084ac19dc52feb4f5952c6df03ffb460a887b42615ee1382e8/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a955b438e62efdf7e0b7b52a64dc5c3396e2634baa62471768a64bc2adb73d5c", size = 153399 }, - { url = "https://files.pythonhosted.org/packages/c2/26/89ee1f0e264d201cb65cf054aca6038c03b1a0c6b4ae998070392a3ce605/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7222ffd5e4de8e57e03ce2cef95a4c43c98fcb72ad86909abdfc2c17d227fc1b", size = 156815 }, - { url = "https://files.pythonhosted.org/packages/fd/07/68e95b4b345bad3dbbd3a8681737b4338ff2c9df29856a6d6d23ac4c73cb/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:bee093bf902e1d8fc0ac143c88902c3dfc8941f7ea1d6a8dd2bcb786d33db03d", size = 154537 }, - { url = "https://files.pythonhosted.org/packages/77/1a/5eefc0ce04affb98af07bc05f3bac9094513c0e23b0562d64af46a06aae4/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb8adb91d11846ee08bec4c8236c8549ac721c245678282dcb06b221aab59f", size = 149565 }, - { url = "https://files.pythonhosted.org/packages/37/a0/2410e5e6032a174c95e0806b1a6585eb21e12f445ebe239fac441995226a/charset_normalizer-3.4.2-cp312-cp312-win32.whl", hash = "sha256:db4c7bf0e07fc3b7d89ac2a5880a6a8062056801b83ff56d8464b70f65482b6c", size = 98357 }, - { url = "https://files.pythonhosted.org/packages/6c/4f/c02d5c493967af3eda9c771ad4d2bbc8df6f99ddbeb37ceea6e8716a32bc/charset_normalizer-3.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:5a9979887252a82fefd3d3ed2a8e3b937a7a809f65dcb1e068b090e165bbe99e", size = 105776 }, - { url = "https://files.pythonhosted.org/packages/ea/12/a93df3366ed32db1d907d7593a94f1fe6293903e3e92967bebd6950ed12c/charset_normalizer-3.4.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0", size = 199622 }, - { url = "https://files.pythonhosted.org/packages/04/93/bf204e6f344c39d9937d3c13c8cd5bbfc266472e51fc8c07cb7f64fcd2de/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf", size = 143435 }, - { url = "https://files.pythonhosted.org/packages/22/2a/ea8a2095b0bafa6c5b5a55ffdc2f924455233ee7b91c69b7edfcc9e02284/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e", size = 153653 }, - { url = "https://files.pythonhosted.org/packages/b6/57/1b090ff183d13cef485dfbe272e2fe57622a76694061353c59da52c9a659/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1", size = 146231 }, - { url = "https://files.pythonhosted.org/packages/e2/28/ffc026b26f441fc67bd21ab7f03b313ab3fe46714a14b516f931abe1a2d8/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c", size = 148243 }, - { url = "https://files.pythonhosted.org/packages/c0/0f/9abe9bd191629c33e69e47c6ef45ef99773320e9ad8e9cb08b8ab4a8d4cb/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691", size = 150442 }, - { url = "https://files.pythonhosted.org/packages/67/7c/a123bbcedca91d5916c056407f89a7f5e8fdfce12ba825d7d6b9954a1a3c/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0", size = 145147 }, - { url = "https://files.pythonhosted.org/packages/ec/fe/1ac556fa4899d967b83e9893788e86b6af4d83e4726511eaaad035e36595/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b", size = 153057 }, - { url = "https://files.pythonhosted.org/packages/2b/ff/acfc0b0a70b19e3e54febdd5301a98b72fa07635e56f24f60502e954c461/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff", size = 156454 }, - { url = "https://files.pythonhosted.org/packages/92/08/95b458ce9c740d0645feb0e96cea1f5ec946ea9c580a94adfe0b617f3573/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b", size = 154174 }, - { url = "https://files.pythonhosted.org/packages/78/be/8392efc43487ac051eee6c36d5fbd63032d78f7728cb37aebcc98191f1ff/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148", size = 149166 }, - { url = "https://files.pythonhosted.org/packages/44/96/392abd49b094d30b91d9fbda6a69519e95802250b777841cf3bda8fe136c/charset_normalizer-3.4.2-cp313-cp313-win32.whl", hash = "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7", size = 98064 }, - { url = "https://files.pythonhosted.org/packages/e9/b0/0200da600134e001d91851ddc797809e2fe0ea72de90e09bec5a2fbdaccb/charset_normalizer-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980", size = 105641 }, - { url = "https://files.pythonhosted.org/packages/20/94/c5790835a017658cbfabd07f3bfb549140c3ac458cfc196323996b10095a/charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0", size = 52626 }, +sdist = { url = "https://files.pythonhosted.org/packages/e4/33/89c2ced2b67d1c2a61c19c6751aa8902d46ce3dacb23600a283619f5a12d/charset_normalizer-3.4.2.tar.gz", hash = "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63", size = 126367, upload-time = "2025-05-02T08:34:42.01Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/28/9901804da60055b406e1a1c5ba7aac1276fb77f1dde635aabfc7fd84b8ab/charset_normalizer-3.4.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c48ed483eb946e6c04ccbe02c6b4d1d48e51944b6db70f697e089c193404941", size = 201818, upload-time = "2025-05-02T08:31:46.725Z" }, + { url = "https://files.pythonhosted.org/packages/d9/9b/892a8c8af9110935e5adcbb06d9c6fe741b6bb02608c6513983048ba1a18/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2d318c11350e10662026ad0eb71bb51c7812fc8590825304ae0bdd4ac283acd", size = 144649, upload-time = "2025-05-02T08:31:48.889Z" }, + { url = "https://files.pythonhosted.org/packages/7b/a5/4179abd063ff6414223575e008593861d62abfc22455b5d1a44995b7c101/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9cbfacf36cb0ec2897ce0ebc5d08ca44213af24265bd56eca54bee7923c48fd6", size = 155045, upload-time = "2025-05-02T08:31:50.757Z" }, + { url = "https://files.pythonhosted.org/packages/3b/95/bc08c7dfeddd26b4be8c8287b9bb055716f31077c8b0ea1cd09553794665/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18dd2e350387c87dabe711b86f83c9c78af772c748904d372ade190b5c7c9d4d", size = 147356, upload-time = "2025-05-02T08:31:52.634Z" }, + { url = "https://files.pythonhosted.org/packages/a8/2d/7a5b635aa65284bf3eab7653e8b4151ab420ecbae918d3e359d1947b4d61/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8075c35cd58273fee266c58c0c9b670947c19df5fb98e7b66710e04ad4e9ff86", size = 149471, upload-time = "2025-05-02T08:31:56.207Z" }, + { url = "https://files.pythonhosted.org/packages/ae/38/51fc6ac74251fd331a8cfdb7ec57beba8c23fd5493f1050f71c87ef77ed0/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5bf4545e3b962767e5c06fe1738f951f77d27967cb2caa64c28be7c4563e162c", size = 151317, upload-time = "2025-05-02T08:31:57.613Z" }, + { url = "https://files.pythonhosted.org/packages/b7/17/edee1e32215ee6e9e46c3e482645b46575a44a2d72c7dfd49e49f60ce6bf/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a6ab32f7210554a96cd9e33abe3ddd86732beeafc7a28e9955cdf22ffadbab0", size = 146368, upload-time = "2025-05-02T08:31:59.468Z" }, + { url = "https://files.pythonhosted.org/packages/26/2c/ea3e66f2b5f21fd00b2825c94cafb8c326ea6240cd80a91eb09e4a285830/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b33de11b92e9f75a2b545d6e9b6f37e398d86c3e9e9653c4864eb7e89c5773ef", size = 154491, upload-time = "2025-05-02T08:32:01.219Z" }, + { url = "https://files.pythonhosted.org/packages/52/47/7be7fa972422ad062e909fd62460d45c3ef4c141805b7078dbab15904ff7/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8755483f3c00d6c9a77f490c17e6ab0c8729e39e6390328e42521ef175380ae6", size = 157695, upload-time = "2025-05-02T08:32:03.045Z" }, + { url = "https://files.pythonhosted.org/packages/2f/42/9f02c194da282b2b340f28e5fb60762de1151387a36842a92b533685c61e/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:68a328e5f55ec37c57f19ebb1fdc56a248db2e3e9ad769919a58672958e8f366", size = 154849, upload-time = "2025-05-02T08:32:04.651Z" }, + { url = "https://files.pythonhosted.org/packages/67/44/89cacd6628f31fb0b63201a618049be4be2a7435a31b55b5eb1c3674547a/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:21b2899062867b0e1fde9b724f8aecb1af14f2778d69aacd1a5a1853a597a5db", size = 150091, upload-time = "2025-05-02T08:32:06.719Z" }, + { url = "https://files.pythonhosted.org/packages/1f/79/4b8da9f712bc079c0f16b6d67b099b0b8d808c2292c937f267d816ec5ecc/charset_normalizer-3.4.2-cp310-cp310-win32.whl", hash = "sha256:e8082b26888e2f8b36a042a58307d5b917ef2b1cacab921ad3323ef91901c71a", size = 98445, upload-time = "2025-05-02T08:32:08.66Z" }, + { url = "https://files.pythonhosted.org/packages/7d/d7/96970afb4fb66497a40761cdf7bd4f6fca0fc7bafde3a84f836c1f57a926/charset_normalizer-3.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:f69a27e45c43520f5487f27627059b64aaf160415589230992cec34c5e18a509", size = 105782, upload-time = "2025-05-02T08:32:10.46Z" }, + { url = "https://files.pythonhosted.org/packages/05/85/4c40d00dcc6284a1c1ad5de5e0996b06f39d8232f1031cd23c2f5c07ee86/charset_normalizer-3.4.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:be1e352acbe3c78727a16a455126d9ff83ea2dfdcbc83148d2982305a04714c2", size = 198794, upload-time = "2025-05-02T08:32:11.945Z" }, + { url = "https://files.pythonhosted.org/packages/41/d9/7a6c0b9db952598e97e93cbdfcb91bacd89b9b88c7c983250a77c008703c/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa88ca0b1932e93f2d961bf3addbb2db902198dca337d88c89e1559e066e7645", size = 142846, upload-time = "2025-05-02T08:32:13.946Z" }, + { url = "https://files.pythonhosted.org/packages/66/82/a37989cda2ace7e37f36c1a8ed16c58cf48965a79c2142713244bf945c89/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d524ba3f1581b35c03cb42beebab4a13e6cdad7b36246bd22541fa585a56cccd", size = 153350, upload-time = "2025-05-02T08:32:15.873Z" }, + { url = "https://files.pythonhosted.org/packages/df/68/a576b31b694d07b53807269d05ec3f6f1093e9545e8607121995ba7a8313/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28a1005facc94196e1fb3e82a3d442a9d9110b8434fc1ded7a24a2983c9888d8", size = 145657, upload-time = "2025-05-02T08:32:17.283Z" }, + { url = "https://files.pythonhosted.org/packages/92/9b/ad67f03d74554bed3aefd56fe836e1623a50780f7c998d00ca128924a499/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdb20a30fe1175ecabed17cbf7812f7b804b8a315a25f24678bcdf120a90077f", size = 147260, upload-time = "2025-05-02T08:32:18.807Z" }, + { url = "https://files.pythonhosted.org/packages/a6/e6/8aebae25e328160b20e31a7e9929b1578bbdc7f42e66f46595a432f8539e/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f5d9ed7f254402c9e7d35d2f5972c9bbea9040e99cd2861bd77dc68263277c7", size = 149164, upload-time = "2025-05-02T08:32:20.333Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f2/b3c2f07dbcc248805f10e67a0262c93308cfa149a4cd3d1fe01f593e5fd2/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:efd387a49825780ff861998cd959767800d54f8308936b21025326de4b5a42b9", size = 144571, upload-time = "2025-05-02T08:32:21.86Z" }, + { url = "https://files.pythonhosted.org/packages/60/5b/c3f3a94bc345bc211622ea59b4bed9ae63c00920e2e8f11824aa5708e8b7/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f0aa37f3c979cf2546b73e8222bbfa3dc07a641585340179d768068e3455e544", size = 151952, upload-time = "2025-05-02T08:32:23.434Z" }, + { url = "https://files.pythonhosted.org/packages/e2/4d/ff460c8b474122334c2fa394a3f99a04cf11c646da895f81402ae54f5c42/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e70e990b2137b29dc5564715de1e12701815dacc1d056308e2b17e9095372a82", size = 155959, upload-time = "2025-05-02T08:32:24.993Z" }, + { url = "https://files.pythonhosted.org/packages/a2/2b/b964c6a2fda88611a1fe3d4c400d39c66a42d6c169c924818c848f922415/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0c8c57f84ccfc871a48a47321cfa49ae1df56cd1d965a09abe84066f6853b9c0", size = 153030, upload-time = "2025-05-02T08:32:26.435Z" }, + { url = "https://files.pythonhosted.org/packages/59/2e/d3b9811db26a5ebf444bc0fa4f4be5aa6d76fc6e1c0fd537b16c14e849b6/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6b66f92b17849b85cad91259efc341dce9c1af48e2173bf38a85c6329f1033e5", size = 148015, upload-time = "2025-05-02T08:32:28.376Z" }, + { url = "https://files.pythonhosted.org/packages/90/07/c5fd7c11eafd561bb51220d600a788f1c8d77c5eef37ee49454cc5c35575/charset_normalizer-3.4.2-cp311-cp311-win32.whl", hash = "sha256:daac4765328a919a805fa5e2720f3e94767abd632ae410a9062dff5412bae65a", size = 98106, upload-time = "2025-05-02T08:32:30.281Z" }, + { url = "https://files.pythonhosted.org/packages/a8/05/5e33dbef7e2f773d672b6d79f10ec633d4a71cd96db6673625838a4fd532/charset_normalizer-3.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53efc7c7cee4c1e70661e2e112ca46a575f90ed9ae3fef200f2a25e954f4b28", size = 105402, upload-time = "2025-05-02T08:32:32.191Z" }, + { url = "https://files.pythonhosted.org/packages/d7/a4/37f4d6035c89cac7930395a35cc0f1b872e652eaafb76a6075943754f095/charset_normalizer-3.4.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0c29de6a1a95f24b9a1aa7aefd27d2487263f00dfd55a77719b530788f75cff7", size = 199936, upload-time = "2025-05-02T08:32:33.712Z" }, + { url = "https://files.pythonhosted.org/packages/ee/8a/1a5e33b73e0d9287274f899d967907cd0bf9c343e651755d9307e0dbf2b3/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cddf7bd982eaa998934a91f69d182aec997c6c468898efe6679af88283b498d3", size = 143790, upload-time = "2025-05-02T08:32:35.768Z" }, + { url = "https://files.pythonhosted.org/packages/66/52/59521f1d8e6ab1482164fa21409c5ef44da3e9f653c13ba71becdd98dec3/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a", size = 153924, upload-time = "2025-05-02T08:32:37.284Z" }, + { url = "https://files.pythonhosted.org/packages/86/2d/fb55fdf41964ec782febbf33cb64be480a6b8f16ded2dbe8db27a405c09f/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d41c4d287cfc69060fa91cae9683eacffad989f1a10811995fa309df656ec214", size = 146626, upload-time = "2025-05-02T08:32:38.803Z" }, + { url = "https://files.pythonhosted.org/packages/8c/73/6ede2ec59bce19b3edf4209d70004253ec5f4e319f9a2e3f2f15601ed5f7/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a", size = 148567, upload-time = "2025-05-02T08:32:40.251Z" }, + { url = "https://files.pythonhosted.org/packages/09/14/957d03c6dc343c04904530b6bef4e5efae5ec7d7990a7cbb868e4595ee30/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf713fe9a71ef6fd5adf7a79670135081cd4431c2943864757f0fa3a65b1fafd", size = 150957, upload-time = "2025-05-02T08:32:41.705Z" }, + { url = "https://files.pythonhosted.org/packages/0d/c8/8174d0e5c10ccebdcb1b53cc959591c4c722a3ad92461a273e86b9f5a302/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a370b3e078e418187da8c3674eddb9d983ec09445c99a3a263c2011993522981", size = 145408, upload-time = "2025-05-02T08:32:43.709Z" }, + { url = "https://files.pythonhosted.org/packages/58/aa/8904b84bc8084ac19dc52feb4f5952c6df03ffb460a887b42615ee1382e8/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a955b438e62efdf7e0b7b52a64dc5c3396e2634baa62471768a64bc2adb73d5c", size = 153399, upload-time = "2025-05-02T08:32:46.197Z" }, + { url = "https://files.pythonhosted.org/packages/c2/26/89ee1f0e264d201cb65cf054aca6038c03b1a0c6b4ae998070392a3ce605/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7222ffd5e4de8e57e03ce2cef95a4c43c98fcb72ad86909abdfc2c17d227fc1b", size = 156815, upload-time = "2025-05-02T08:32:48.105Z" }, + { url = "https://files.pythonhosted.org/packages/fd/07/68e95b4b345bad3dbbd3a8681737b4338ff2c9df29856a6d6d23ac4c73cb/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:bee093bf902e1d8fc0ac143c88902c3dfc8941f7ea1d6a8dd2bcb786d33db03d", size = 154537, upload-time = "2025-05-02T08:32:49.719Z" }, + { url = "https://files.pythonhosted.org/packages/77/1a/5eefc0ce04affb98af07bc05f3bac9094513c0e23b0562d64af46a06aae4/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb8adb91d11846ee08bec4c8236c8549ac721c245678282dcb06b221aab59f", size = 149565, upload-time = "2025-05-02T08:32:51.404Z" }, + { url = "https://files.pythonhosted.org/packages/37/a0/2410e5e6032a174c95e0806b1a6585eb21e12f445ebe239fac441995226a/charset_normalizer-3.4.2-cp312-cp312-win32.whl", hash = "sha256:db4c7bf0e07fc3b7d89ac2a5880a6a8062056801b83ff56d8464b70f65482b6c", size = 98357, upload-time = "2025-05-02T08:32:53.079Z" }, + { url = "https://files.pythonhosted.org/packages/6c/4f/c02d5c493967af3eda9c771ad4d2bbc8df6f99ddbeb37ceea6e8716a32bc/charset_normalizer-3.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:5a9979887252a82fefd3d3ed2a8e3b937a7a809f65dcb1e068b090e165bbe99e", size = 105776, upload-time = "2025-05-02T08:32:54.573Z" }, + { url = "https://files.pythonhosted.org/packages/ea/12/a93df3366ed32db1d907d7593a94f1fe6293903e3e92967bebd6950ed12c/charset_normalizer-3.4.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0", size = 199622, upload-time = "2025-05-02T08:32:56.363Z" }, + { url = "https://files.pythonhosted.org/packages/04/93/bf204e6f344c39d9937d3c13c8cd5bbfc266472e51fc8c07cb7f64fcd2de/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf", size = 143435, upload-time = "2025-05-02T08:32:58.551Z" }, + { url = "https://files.pythonhosted.org/packages/22/2a/ea8a2095b0bafa6c5b5a55ffdc2f924455233ee7b91c69b7edfcc9e02284/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e", size = 153653, upload-time = "2025-05-02T08:33:00.342Z" }, + { url = "https://files.pythonhosted.org/packages/b6/57/1b090ff183d13cef485dfbe272e2fe57622a76694061353c59da52c9a659/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1", size = 146231, upload-time = "2025-05-02T08:33:02.081Z" }, + { url = "https://files.pythonhosted.org/packages/e2/28/ffc026b26f441fc67bd21ab7f03b313ab3fe46714a14b516f931abe1a2d8/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c", size = 148243, upload-time = "2025-05-02T08:33:04.063Z" }, + { url = "https://files.pythonhosted.org/packages/c0/0f/9abe9bd191629c33e69e47c6ef45ef99773320e9ad8e9cb08b8ab4a8d4cb/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691", size = 150442, upload-time = "2025-05-02T08:33:06.418Z" }, + { url = "https://files.pythonhosted.org/packages/67/7c/a123bbcedca91d5916c056407f89a7f5e8fdfce12ba825d7d6b9954a1a3c/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0", size = 145147, upload-time = "2025-05-02T08:33:08.183Z" }, + { url = "https://files.pythonhosted.org/packages/ec/fe/1ac556fa4899d967b83e9893788e86b6af4d83e4726511eaaad035e36595/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b", size = 153057, upload-time = "2025-05-02T08:33:09.986Z" }, + { url = "https://files.pythonhosted.org/packages/2b/ff/acfc0b0a70b19e3e54febdd5301a98b72fa07635e56f24f60502e954c461/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff", size = 156454, upload-time = "2025-05-02T08:33:11.814Z" }, + { url = "https://files.pythonhosted.org/packages/92/08/95b458ce9c740d0645feb0e96cea1f5ec946ea9c580a94adfe0b617f3573/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b", size = 154174, upload-time = "2025-05-02T08:33:13.707Z" }, + { url = "https://files.pythonhosted.org/packages/78/be/8392efc43487ac051eee6c36d5fbd63032d78f7728cb37aebcc98191f1ff/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148", size = 149166, upload-time = "2025-05-02T08:33:15.458Z" }, + { url = "https://files.pythonhosted.org/packages/44/96/392abd49b094d30b91d9fbda6a69519e95802250b777841cf3bda8fe136c/charset_normalizer-3.4.2-cp313-cp313-win32.whl", hash = "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7", size = 98064, upload-time = "2025-05-02T08:33:17.06Z" }, + { url = "https://files.pythonhosted.org/packages/e9/b0/0200da600134e001d91851ddc797809e2fe0ea72de90e09bec5a2fbdaccb/charset_normalizer-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980", size = 105641, upload-time = "2025-05-02T08:33:18.753Z" }, + { url = "https://files.pythonhosted.org/packages/20/94/c5790835a017658cbfabd07f3bfb549140c3ac458cfc196323996b10095a/charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0", size = 52626, upload-time = "2025-05-02T08:34:40.053Z" }, ] [[package]] name = "ckzg" version = "2.1.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/55/df/f6db8e83bd4594c1ea685cd37fb81d5399e55765aae16d1a8a9502598f4e/ckzg-2.1.1.tar.gz", hash = "sha256:d6b306b7ec93a24e4346aa53d07f7f75053bc0afc7398e35fa649e5f9d48fcc4", size = 1120500 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/33/4b/cd25e857cdf46a752e97c530fe2582fae77c4d16c29fff5a15b7a998e2fd/ckzg-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4b9825a1458219e8b4b023012b8ef027ef1f47e903f9541cbca4615f80132730", size = 116377 }, - { url = "https://files.pythonhosted.org/packages/7e/bc/5dfef36589545f797245ecacb54ed2acfa75507f63cfe12182d1277a88f1/ckzg-2.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e2a40a3ba65cca4b52825d26829e6f7eb464aa27a9e9efb6b8b2ce183442c741", size = 100208 }, - { url = "https://files.pythonhosted.org/packages/b7/52/96f0e3affbed321dc52b9b4ca13e0fb594da572d1f8edc47378fe48d8e9a/ckzg-2.1.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a1d753fbe85be7c21602eddc2d40e0915e25fce10329f4f801a0002a4f886cc7", size = 174800 }, - { url = "https://files.pythonhosted.org/packages/dc/21/b1bc07cc8e5ed32817e89b054e2399d38775d92ff2d55e24bf233f537c02/ckzg-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d76b50527f1d12430bf118aff6fa4051e9860eada43f29177258b8d399448ea", size = 160847 }, - { url = "https://files.pythonhosted.org/packages/c9/5a/97b173d4ff9bce798031beb12b340c4f1729eaaddd07f69f368f843db28e/ckzg-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44c8603e43c021d100f355f50189183135d1df3cbbddb8881552d57fbf421dde", size = 169712 }, - { url = "https://files.pythonhosted.org/packages/7b/52/48be78c07f362438e189e2fbea7df8543290c3ee99845442549c8dc5405b/ckzg-2.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:38707a638c9d715b3c30b29352b969f78d8fc10faed7db5faf517f04359895c0", size = 172942 }, - { url = "https://files.pythonhosted.org/packages/13/42/3cfcd6cbdfb9030b9071d5e413a458f93883e47ad4a7d8d4c1d57608e57d/ckzg-2.1.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:52c4d257bdcbe822d20c5cd24c8154ec5aac33c49a8f5a19e716d9107a1c8785", size = 187707 }, - { url = "https://files.pythonhosted.org/packages/eb/54/d43bc3a2de486fb8be29ffedc3ec80f5726765ee4fa78beabe2ab2440f93/ckzg-2.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1507f7bfb9bcf51d816db5d8d0f0ed53c8289605137820d437b69daea8333e16", size = 182505 }, - { url = "https://files.pythonhosted.org/packages/21/43/5bcd2b7630732b532006572fbb8d64a29f69530c630ae4811167a2a0dc3b/ckzg-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:d02eaaf4f841910133552b3a051dea53bcfe60cd98199fc4cf80b27609d8baa2", size = 98822 }, - { url = "https://files.pythonhosted.org/packages/95/2c/44120b2d9dcb0246d67a1f28b9eaa625c499014d4d42561467e28eedd285/ckzg-2.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:465e2b71cf9dc383f66f1979269420a0da9274a3a9e98b1a4455e84927dfe491", size = 116378 }, - { url = "https://files.pythonhosted.org/packages/23/88/c5b89ba9a730fee5e089be9e0c7048fb6707c1a0e4b6c30fcf725c3eef44/ckzg-2.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ee2f26f17a64ad0aab833d637b276f28486b82a29e34f32cf54b237b8f8ab72d", size = 100202 }, - { url = "https://files.pythonhosted.org/packages/ee/11/b0a473e80346db52ad9a629bc9fd8f773c718ed78932ea3a70392306ffc3/ckzg-2.1.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99cc2c4e9fb8c62e3e0862c7f4df9142f07ba640da17fded5f6e0fd09f75909f", size = 175595 }, - { url = "https://files.pythonhosted.org/packages/52/fa/17a7e125d07a96dd6dce4db7262231f7583856b2be5d5b7df59e04bfa188/ckzg-2.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:773dd016693d74aca1f5d7982db2bad7dde2e147563aeb16a783f7e5f69c01fe", size = 161681 }, - { url = "https://files.pythonhosted.org/packages/57/bd/46d6b90bf53da732f9adab7593d132a0834ed4f2f7659b4c7414d8f78d39/ckzg-2.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af2b2144f87ba218d8db01382a961b3ecbdde5ede4fa0d9428d35f8c8a595ba", size = 170471 }, - { url = "https://files.pythonhosted.org/packages/9d/98/113c7704749d037d75f23240ffc5c46dfe8416de574b946438587835715f/ckzg-2.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8f55e63d3f7c934a2cb53728ed1d815479e177aca8c84efe991c2920977cff6", size = 173595 }, - { url = "https://files.pythonhosted.org/packages/2f/d5/05fca6dcb5a19327be491157794eafc3d7498daf615c2ff5a5b745852945/ckzg-2.1.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ecb42aaa0ffa427ff14a9dde9356ba69e5ae6014650b397af55b31bdae7a9b6e", size = 188417 }, - { url = "https://files.pythonhosted.org/packages/72/36/131ae2dfc82d0fdc98fae8e3bbfe71ff14265bb434b23bd07b585afc6d61/ckzg-2.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5a01514239f12fb1a7ad9009c20062a4496e13b09541c1a65f97e295da648c70", size = 183286 }, - { url = "https://files.pythonhosted.org/packages/c5/6a/d371b27024422b25228fc11fa57b1ba7756a94cc9fb0c75da292c235fdaa/ckzg-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:6516b9684aae262c85cf7fddd8b585b8139ad20e08ec03994e219663abbb0916", size = 98819 }, - { url = "https://files.pythonhosted.org/packages/93/a1/9c07513dd0ea01e5db727e67bd2660f3b300a4511281cdb8d5e04afa1cfd/ckzg-2.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c60e8903344ce98ce036f0fabacce952abb714cad4607198b2f0961c28b8aa72", size = 116421 }, - { url = "https://files.pythonhosted.org/packages/27/04/b69a0dfbb2722a14c98a52973f276679151ec56a14178cb48e6f2e1697bc/ckzg-2.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4299149dd72448e5a8d2d1cc6cc7472c92fc9d9f00b1377f5b017c089d9cd92", size = 100216 }, - { url = "https://files.pythonhosted.org/packages/2e/24/9cc850d0b8ead395ad5064de67c7c91adacaf31b6b35292ab53fbd93270b/ckzg-2.1.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:025dd31ffdcc799f3ff842570a2a6683b6c5b01567da0109c0c05d11768729c4", size = 175764 }, - { url = "https://files.pythonhosted.org/packages/c0/c1/eb13ba399082a98b932f10b230ec08e6456051c0ce3886b3f6d8548d11ab/ckzg-2.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b42ab8385c273f40a693657c09d2bba40cb4f4666141e263906ba2e519e80bd", size = 161885 }, - { url = "https://files.pythonhosted.org/packages/57/c7/58baa64199781950c5a8c6139a46e1acff0f057a36e56769817400eb87fb/ckzg-2.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1be3890fc1543f4fcfc0063e4baf5c036eb14bcf736dabdc6171ab017e0f1671", size = 170757 }, - { url = "https://files.pythonhosted.org/packages/65/bd/4b8e1c70972c98829371b7004dc750a45268c5d3442d602e1b62f13ca867/ckzg-2.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b754210ded172968b201e2d7252573af6bf52d6ad127ddd13d0b9a45a51dae7b", size = 173761 }, - { url = "https://files.pythonhosted.org/packages/1f/32/c3fd1002f97ba3e0c5b1d9ab2c8fb7a6f475fa9b80ed9c4fa55975501a54/ckzg-2.1.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b2f8fda87865897a269c4e951e3826c2e814427a6cdfed6731cccfe548f12b36", size = 188666 }, - { url = "https://files.pythonhosted.org/packages/e2/d9/91cf5a8169ee60c9397c975163cbca34432571f94facec5f8c0086bb47d8/ckzg-2.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:98e70b5923d77c7359432490145e9d1ab0bf873eb5de56ec53f4a551d7eaec79", size = 183652 }, - { url = "https://files.pythonhosted.org/packages/25/d4/8c9f6b852f99926862344b29f0c59681916ccfec2ac60a85952a369e0bca/ckzg-2.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:42af7bde4ca45469cd93a96c3d15d69d51d40e7f0d30e3a20711ebd639465fcb", size = 98816 }, - { url = "https://files.pythonhosted.org/packages/b7/9a/fa698b12e97452d11dd314e0335aae759725284ef6e1c1665aed56b1cd3e/ckzg-2.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7e4edfdaf87825ff43b9885fabfdea408737a714f4ce5467100d9d1d0a03b673", size = 116426 }, - { url = "https://files.pythonhosted.org/packages/a1/a6/8cccd308bd11b49b40eecad6900b5769da117951cac33e880dd25e851ef7/ckzg-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:815fd2a87d6d6c57d669fda30c150bc9bf387d47e67d84535aa42b909fdc28ea", size = 100219 }, - { url = "https://files.pythonhosted.org/packages/30/0e/63573d816c1292b9a4d70eb6a7366b3593d29a977794039e926805a76ca0/ckzg-2.1.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c32466e809b1ab3ff01d3b0bb0b9912f61dcf72957885615595f75e3f7cc10e5", size = 175725 }, - { url = "https://files.pythonhosted.org/packages/86/f6/a279609516695ad3fb8b201098c669ba3b2844cbf4fa0d83a0f02b9bb29b/ckzg-2.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f11b73ccf37b12993f39a7dbace159c6d580aacacde6ee17282848476550ddbc", size = 161835 }, - { url = "https://files.pythonhosted.org/packages/39/e4/8cf7aef7dc05a777cb221e94046f947c6fe5317159a8dae2cd7090d52ef2/ckzg-2.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de3b9433a1f2604bd9ac1646d3c83ad84a850d454d3ac589fe8e70c94b38a6b0", size = 170759 }, - { url = "https://files.pythonhosted.org/packages/0b/17/b34e3c08eb36bc67e338b114f289b2595e581b8bdc09a8f12299a1db5d2f/ckzg-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b7d7e1b5ea06234558cd95c483666fd785a629b720a7f1622b3cbffebdc62033", size = 173787 }, - { url = "https://files.pythonhosted.org/packages/2e/f0/aff87c3ed80713453cb6c84fe6fbb7582d86a7a5e4460fda2a497d47f489/ckzg-2.1.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9f5556e6675866040cc4335907be6c537051e7f668da289fa660fdd8a30c9ddb", size = 188722 }, - { url = "https://files.pythonhosted.org/packages/44/d9/1f08bfb8fd1cbb8c7513e7ad3fb76bbb5c3fb446238c1eba582276e4d905/ckzg-2.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:55b2ba30c5c9daac0c55f1aac851f1b7bf1f7aa0028c2db4440e963dd5b866d6", size = 183686 }, - { url = "https://files.pythonhosted.org/packages/a3/ff/434f6d2893cbdfad00c20d17e9a52d426ca042f5e980d5c3db96bc6b6e15/ckzg-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:10d201601fc8f28c0e8cec3406676797024dd374c367bbeec5a7a9eac9147237", size = 98817 }, - { url = "https://files.pythonhosted.org/packages/30/b3/a0c7d7ba6e669cf04605dc0329173db62fc1fe3c488761755cc01e5e1b4d/ckzg-2.1.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:375918e25eafb9bafe5215ab91698504cba3fe51b4fe92f5896af6c5663f50c6", size = 113191 }, - { url = "https://files.pythonhosted.org/packages/f2/b9/a6cf403b8528d18d7d9154e28381a397bf466c86aa8e0b3327cffdde5749/ckzg-2.1.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:38b3b7802c76d4ad015db2b7a79a49c193babae50ee5f77e9ac2865c9e9ddb09", size = 96207 }, - { url = "https://files.pythonhosted.org/packages/63/6b/5ddd713d97886becb8450e3e13db891199125f722366d30d087ad5438390/ckzg-2.1.1-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:438a5009fd254ace0bc1ad974d524547f1a41e6aa5e778c5cd41f4ee3106bcd6", size = 126160 }, - { url = "https://files.pythonhosted.org/packages/c7/dd/e05aecc01e62108a7579f8df5e5d38536841f50e12172f8a84677edac0fa/ckzg-2.1.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ce11cc163a2e0dab3af7455aca7053f9d5bb8d157f231acc7665fd230565d48", size = 102811 }, - { url = "https://files.pythonhosted.org/packages/c6/81/6cdadd8626ac11290af3f58ae5dcffe38bd2c8f8c798dacee7475e244aac/ckzg-2.1.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b53964c07f6a076e97eaa1ef35045e935d7040aff14f80bae7e9105717702d05", size = 111328 }, - { url = "https://files.pythonhosted.org/packages/36/b7/b129ff6955cd264c6ab3dbd52dd1b2759d1b121c09c03f9991e4c722c72f/ckzg-2.1.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:cf085f15ae52ab2599c9b5a3d5842794bcf5613b7f58661fbfb0c5d9eac988b9", size = 98846 }, - { url = "https://files.pythonhosted.org/packages/7f/ba/7d9c1f9cec7e0e382653c72165896194a05743e589b1dae2aa80236aa87f/ckzg-2.1.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:4b0c850bd6cad22ac79b2a2ab884e0e7cd2b54a67d643cd616c145ebdb535a11", size = 113188 }, - { url = "https://files.pythonhosted.org/packages/2f/92/9728f5ccc1c5e87c6c5ae7941250a447b61fd5a63aadbc15249e29c21bcf/ckzg-2.1.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:26951f36bb60c9150bbd38110f5e1625596f9779dad54d1d492d8ec38bc84e3a", size = 96208 }, - { url = "https://files.pythonhosted.org/packages/39/63/5e27d587bd224fee70cb66b022e7c4ef95d0e091e08ee76c25ec12094b0d/ckzg-2.1.1-pp311-pypy311_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bbe12445e49c4bee67746b7b958e90a973b0de116d0390749b0df351d94e9a8c", size = 126158 }, - { url = "https://files.pythonhosted.org/packages/43/98/e0a45946575a7b823d8ee0b47afb104b6017e54e1208f07da2529bc01900/ckzg-2.1.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71c5d4f66f09de4a99271acac74d2acb3559a77de77a366b34a91e99e8822667", size = 102812 }, - { url = "https://files.pythonhosted.org/packages/cb/50/718ca7b03e4b89b18cdf99cc3038050105b0acbf9b612c23cd513093c6de/ckzg-2.1.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42673c1d007372a4e8b48f6ef8f0ce31a9688a463317a98539757d1e2fb1ecc7", size = 111327 }, - { url = "https://files.pythonhosted.org/packages/29/c5/80e5a0c6967d02d801150104320484a258e5a49bd191e198643e74039320/ckzg-2.1.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:57a7dc41ec6b69c1d9117eb61cf001295e6b4f67a736020442e71fb4367fb1a5", size = 98847 }, +sdist = { url = "https://files.pythonhosted.org/packages/55/df/f6db8e83bd4594c1ea685cd37fb81d5399e55765aae16d1a8a9502598f4e/ckzg-2.1.1.tar.gz", hash = "sha256:d6b306b7ec93a24e4346aa53d07f7f75053bc0afc7398e35fa649e5f9d48fcc4", size = 1120500, upload-time = "2025-03-31T21:24:12.324Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/33/4b/cd25e857cdf46a752e97c530fe2582fae77c4d16c29fff5a15b7a998e2fd/ckzg-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4b9825a1458219e8b4b023012b8ef027ef1f47e903f9541cbca4615f80132730", size = 116377, upload-time = "2025-03-31T21:22:26.952Z" }, + { url = "https://files.pythonhosted.org/packages/7e/bc/5dfef36589545f797245ecacb54ed2acfa75507f63cfe12182d1277a88f1/ckzg-2.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e2a40a3ba65cca4b52825d26829e6f7eb464aa27a9e9efb6b8b2ce183442c741", size = 100208, upload-time = "2025-03-31T21:22:28.04Z" }, + { url = "https://files.pythonhosted.org/packages/b7/52/96f0e3affbed321dc52b9b4ca13e0fb594da572d1f8edc47378fe48d8e9a/ckzg-2.1.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a1d753fbe85be7c21602eddc2d40e0915e25fce10329f4f801a0002a4f886cc7", size = 174800, upload-time = "2025-03-31T21:22:29.719Z" }, + { url = "https://files.pythonhosted.org/packages/dc/21/b1bc07cc8e5ed32817e89b054e2399d38775d92ff2d55e24bf233f537c02/ckzg-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d76b50527f1d12430bf118aff6fa4051e9860eada43f29177258b8d399448ea", size = 160847, upload-time = "2025-03-31T21:22:30.973Z" }, + { url = "https://files.pythonhosted.org/packages/c9/5a/97b173d4ff9bce798031beb12b340c4f1729eaaddd07f69f368f843db28e/ckzg-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44c8603e43c021d100f355f50189183135d1df3cbbddb8881552d57fbf421dde", size = 169712, upload-time = "2025-03-31T21:22:31.881Z" }, + { url = "https://files.pythonhosted.org/packages/7b/52/48be78c07f362438e189e2fbea7df8543290c3ee99845442549c8dc5405b/ckzg-2.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:38707a638c9d715b3c30b29352b969f78d8fc10faed7db5faf517f04359895c0", size = 172942, upload-time = "2025-03-31T21:22:32.8Z" }, + { url = "https://files.pythonhosted.org/packages/13/42/3cfcd6cbdfb9030b9071d5e413a458f93883e47ad4a7d8d4c1d57608e57d/ckzg-2.1.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:52c4d257bdcbe822d20c5cd24c8154ec5aac33c49a8f5a19e716d9107a1c8785", size = 187707, upload-time = "2025-03-31T21:22:33.673Z" }, + { url = "https://files.pythonhosted.org/packages/eb/54/d43bc3a2de486fb8be29ffedc3ec80f5726765ee4fa78beabe2ab2440f93/ckzg-2.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1507f7bfb9bcf51d816db5d8d0f0ed53c8289605137820d437b69daea8333e16", size = 182505, upload-time = "2025-03-31T21:22:34.563Z" }, + { url = "https://files.pythonhosted.org/packages/21/43/5bcd2b7630732b532006572fbb8d64a29f69530c630ae4811167a2a0dc3b/ckzg-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:d02eaaf4f841910133552b3a051dea53bcfe60cd98199fc4cf80b27609d8baa2", size = 98822, upload-time = "2025-03-31T21:22:35.786Z" }, + { url = "https://files.pythonhosted.org/packages/95/2c/44120b2d9dcb0246d67a1f28b9eaa625c499014d4d42561467e28eedd285/ckzg-2.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:465e2b71cf9dc383f66f1979269420a0da9274a3a9e98b1a4455e84927dfe491", size = 116378, upload-time = "2025-03-31T21:22:36.96Z" }, + { url = "https://files.pythonhosted.org/packages/23/88/c5b89ba9a730fee5e089be9e0c7048fb6707c1a0e4b6c30fcf725c3eef44/ckzg-2.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ee2f26f17a64ad0aab833d637b276f28486b82a29e34f32cf54b237b8f8ab72d", size = 100202, upload-time = "2025-03-31T21:22:37.799Z" }, + { url = "https://files.pythonhosted.org/packages/ee/11/b0a473e80346db52ad9a629bc9fd8f773c718ed78932ea3a70392306ffc3/ckzg-2.1.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99cc2c4e9fb8c62e3e0862c7f4df9142f07ba640da17fded5f6e0fd09f75909f", size = 175595, upload-time = "2025-03-31T21:22:39.013Z" }, + { url = "https://files.pythonhosted.org/packages/52/fa/17a7e125d07a96dd6dce4db7262231f7583856b2be5d5b7df59e04bfa188/ckzg-2.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:773dd016693d74aca1f5d7982db2bad7dde2e147563aeb16a783f7e5f69c01fe", size = 161681, upload-time = "2025-03-31T21:22:40.257Z" }, + { url = "https://files.pythonhosted.org/packages/57/bd/46d6b90bf53da732f9adab7593d132a0834ed4f2f7659b4c7414d8f78d39/ckzg-2.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af2b2144f87ba218d8db01382a961b3ecbdde5ede4fa0d9428d35f8c8a595ba", size = 170471, upload-time = "2025-03-31T21:22:41.513Z" }, + { url = "https://files.pythonhosted.org/packages/9d/98/113c7704749d037d75f23240ffc5c46dfe8416de574b946438587835715f/ckzg-2.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8f55e63d3f7c934a2cb53728ed1d815479e177aca8c84efe991c2920977cff6", size = 173595, upload-time = "2025-03-31T21:22:42.534Z" }, + { url = "https://files.pythonhosted.org/packages/2f/d5/05fca6dcb5a19327be491157794eafc3d7498daf615c2ff5a5b745852945/ckzg-2.1.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ecb42aaa0ffa427ff14a9dde9356ba69e5ae6014650b397af55b31bdae7a9b6e", size = 188417, upload-time = "2025-03-31T21:22:43.466Z" }, + { url = "https://files.pythonhosted.org/packages/72/36/131ae2dfc82d0fdc98fae8e3bbfe71ff14265bb434b23bd07b585afc6d61/ckzg-2.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5a01514239f12fb1a7ad9009c20062a4496e13b09541c1a65f97e295da648c70", size = 183286, upload-time = "2025-03-31T21:22:44.732Z" }, + { url = "https://files.pythonhosted.org/packages/c5/6a/d371b27024422b25228fc11fa57b1ba7756a94cc9fb0c75da292c235fdaa/ckzg-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:6516b9684aae262c85cf7fddd8b585b8139ad20e08ec03994e219663abbb0916", size = 98819, upload-time = "2025-03-31T21:22:45.57Z" }, + { url = "https://files.pythonhosted.org/packages/93/a1/9c07513dd0ea01e5db727e67bd2660f3b300a4511281cdb8d5e04afa1cfd/ckzg-2.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c60e8903344ce98ce036f0fabacce952abb714cad4607198b2f0961c28b8aa72", size = 116421, upload-time = "2025-03-31T21:22:46.434Z" }, + { url = "https://files.pythonhosted.org/packages/27/04/b69a0dfbb2722a14c98a52973f276679151ec56a14178cb48e6f2e1697bc/ckzg-2.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4299149dd72448e5a8d2d1cc6cc7472c92fc9d9f00b1377f5b017c089d9cd92", size = 100216, upload-time = "2025-03-31T21:22:47.633Z" }, + { url = "https://files.pythonhosted.org/packages/2e/24/9cc850d0b8ead395ad5064de67c7c91adacaf31b6b35292ab53fbd93270b/ckzg-2.1.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:025dd31ffdcc799f3ff842570a2a6683b6c5b01567da0109c0c05d11768729c4", size = 175764, upload-time = "2025-03-31T21:22:48.768Z" }, + { url = "https://files.pythonhosted.org/packages/c0/c1/eb13ba399082a98b932f10b230ec08e6456051c0ce3886b3f6d8548d11ab/ckzg-2.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b42ab8385c273f40a693657c09d2bba40cb4f4666141e263906ba2e519e80bd", size = 161885, upload-time = "2025-03-31T21:22:50.05Z" }, + { url = "https://files.pythonhosted.org/packages/57/c7/58baa64199781950c5a8c6139a46e1acff0f057a36e56769817400eb87fb/ckzg-2.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1be3890fc1543f4fcfc0063e4baf5c036eb14bcf736dabdc6171ab017e0f1671", size = 170757, upload-time = "2025-03-31T21:22:51.282Z" }, + { url = "https://files.pythonhosted.org/packages/65/bd/4b8e1c70972c98829371b7004dc750a45268c5d3442d602e1b62f13ca867/ckzg-2.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b754210ded172968b201e2d7252573af6bf52d6ad127ddd13d0b9a45a51dae7b", size = 173761, upload-time = "2025-03-31T21:22:52.6Z" }, + { url = "https://files.pythonhosted.org/packages/1f/32/c3fd1002f97ba3e0c5b1d9ab2c8fb7a6f475fa9b80ed9c4fa55975501a54/ckzg-2.1.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b2f8fda87865897a269c4e951e3826c2e814427a6cdfed6731cccfe548f12b36", size = 188666, upload-time = "2025-03-31T21:22:53.47Z" }, + { url = "https://files.pythonhosted.org/packages/e2/d9/91cf5a8169ee60c9397c975163cbca34432571f94facec5f8c0086bb47d8/ckzg-2.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:98e70b5923d77c7359432490145e9d1ab0bf873eb5de56ec53f4a551d7eaec79", size = 183652, upload-time = "2025-03-31T21:22:54.351Z" }, + { url = "https://files.pythonhosted.org/packages/25/d4/8c9f6b852f99926862344b29f0c59681916ccfec2ac60a85952a369e0bca/ckzg-2.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:42af7bde4ca45469cd93a96c3d15d69d51d40e7f0d30e3a20711ebd639465fcb", size = 98816, upload-time = "2025-03-31T21:22:55.23Z" }, + { url = "https://files.pythonhosted.org/packages/b7/9a/fa698b12e97452d11dd314e0335aae759725284ef6e1c1665aed56b1cd3e/ckzg-2.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7e4edfdaf87825ff43b9885fabfdea408737a714f4ce5467100d9d1d0a03b673", size = 116426, upload-time = "2025-03-31T21:22:56.108Z" }, + { url = "https://files.pythonhosted.org/packages/a1/a6/8cccd308bd11b49b40eecad6900b5769da117951cac33e880dd25e851ef7/ckzg-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:815fd2a87d6d6c57d669fda30c150bc9bf387d47e67d84535aa42b909fdc28ea", size = 100219, upload-time = "2025-03-31T21:22:56.982Z" }, + { url = "https://files.pythonhosted.org/packages/30/0e/63573d816c1292b9a4d70eb6a7366b3593d29a977794039e926805a76ca0/ckzg-2.1.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c32466e809b1ab3ff01d3b0bb0b9912f61dcf72957885615595f75e3f7cc10e5", size = 175725, upload-time = "2025-03-31T21:22:58.213Z" }, + { url = "https://files.pythonhosted.org/packages/86/f6/a279609516695ad3fb8b201098c669ba3b2844cbf4fa0d83a0f02b9bb29b/ckzg-2.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f11b73ccf37b12993f39a7dbace159c6d580aacacde6ee17282848476550ddbc", size = 161835, upload-time = "2025-03-31T21:22:59.448Z" }, + { url = "https://files.pythonhosted.org/packages/39/e4/8cf7aef7dc05a777cb221e94046f947c6fe5317159a8dae2cd7090d52ef2/ckzg-2.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de3b9433a1f2604bd9ac1646d3c83ad84a850d454d3ac589fe8e70c94b38a6b0", size = 170759, upload-time = "2025-03-31T21:23:01.022Z" }, + { url = "https://files.pythonhosted.org/packages/0b/17/b34e3c08eb36bc67e338b114f289b2595e581b8bdc09a8f12299a1db5d2f/ckzg-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b7d7e1b5ea06234558cd95c483666fd785a629b720a7f1622b3cbffebdc62033", size = 173787, upload-time = "2025-03-31T21:23:01.974Z" }, + { url = "https://files.pythonhosted.org/packages/2e/f0/aff87c3ed80713453cb6c84fe6fbb7582d86a7a5e4460fda2a497d47f489/ckzg-2.1.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9f5556e6675866040cc4335907be6c537051e7f668da289fa660fdd8a30c9ddb", size = 188722, upload-time = "2025-03-31T21:23:02.966Z" }, + { url = "https://files.pythonhosted.org/packages/44/d9/1f08bfb8fd1cbb8c7513e7ad3fb76bbb5c3fb446238c1eba582276e4d905/ckzg-2.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:55b2ba30c5c9daac0c55f1aac851f1b7bf1f7aa0028c2db4440e963dd5b866d6", size = 183686, upload-time = "2025-03-31T21:23:03.905Z" }, + { url = "https://files.pythonhosted.org/packages/a3/ff/434f6d2893cbdfad00c20d17e9a52d426ca042f5e980d5c3db96bc6b6e15/ckzg-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:10d201601fc8f28c0e8cec3406676797024dd374c367bbeec5a7a9eac9147237", size = 98817, upload-time = "2025-03-31T21:23:05.2Z" }, + { url = "https://files.pythonhosted.org/packages/30/b3/a0c7d7ba6e669cf04605dc0329173db62fc1fe3c488761755cc01e5e1b4d/ckzg-2.1.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:375918e25eafb9bafe5215ab91698504cba3fe51b4fe92f5896af6c5663f50c6", size = 113191, upload-time = "2025-03-31T21:23:40.646Z" }, + { url = "https://files.pythonhosted.org/packages/f2/b9/a6cf403b8528d18d7d9154e28381a397bf466c86aa8e0b3327cffdde5749/ckzg-2.1.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:38b3b7802c76d4ad015db2b7a79a49c193babae50ee5f77e9ac2865c9e9ddb09", size = 96207, upload-time = "2025-03-31T21:23:41.596Z" }, + { url = "https://files.pythonhosted.org/packages/63/6b/5ddd713d97886becb8450e3e13db891199125f722366d30d087ad5438390/ckzg-2.1.1-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:438a5009fd254ace0bc1ad974d524547f1a41e6aa5e778c5cd41f4ee3106bcd6", size = 126160, upload-time = "2025-03-31T21:23:42.553Z" }, + { url = "https://files.pythonhosted.org/packages/c7/dd/e05aecc01e62108a7579f8df5e5d38536841f50e12172f8a84677edac0fa/ckzg-2.1.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ce11cc163a2e0dab3af7455aca7053f9d5bb8d157f231acc7665fd230565d48", size = 102811, upload-time = "2025-03-31T21:23:43.494Z" }, + { url = "https://files.pythonhosted.org/packages/c6/81/6cdadd8626ac11290af3f58ae5dcffe38bd2c8f8c798dacee7475e244aac/ckzg-2.1.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b53964c07f6a076e97eaa1ef35045e935d7040aff14f80bae7e9105717702d05", size = 111328, upload-time = "2025-03-31T21:23:44.449Z" }, + { url = "https://files.pythonhosted.org/packages/36/b7/b129ff6955cd264c6ab3dbd52dd1b2759d1b121c09c03f9991e4c722c72f/ckzg-2.1.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:cf085f15ae52ab2599c9b5a3d5842794bcf5613b7f58661fbfb0c5d9eac988b9", size = 98846, upload-time = "2025-03-31T21:23:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7f/ba/7d9c1f9cec7e0e382653c72165896194a05743e589b1dae2aa80236aa87f/ckzg-2.1.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:4b0c850bd6cad22ac79b2a2ab884e0e7cd2b54a67d643cd616c145ebdb535a11", size = 113188, upload-time = "2025-03-31T21:23:46.337Z" }, + { url = "https://files.pythonhosted.org/packages/2f/92/9728f5ccc1c5e87c6c5ae7941250a447b61fd5a63aadbc15249e29c21bcf/ckzg-2.1.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:26951f36bb60c9150bbd38110f5e1625596f9779dad54d1d492d8ec38bc84e3a", size = 96208, upload-time = "2025-03-31T21:23:47.255Z" }, + { url = "https://files.pythonhosted.org/packages/39/63/5e27d587bd224fee70cb66b022e7c4ef95d0e091e08ee76c25ec12094b0d/ckzg-2.1.1-pp311-pypy311_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bbe12445e49c4bee67746b7b958e90a973b0de116d0390749b0df351d94e9a8c", size = 126158, upload-time = "2025-03-31T21:23:48.195Z" }, + { url = "https://files.pythonhosted.org/packages/43/98/e0a45946575a7b823d8ee0b47afb104b6017e54e1208f07da2529bc01900/ckzg-2.1.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71c5d4f66f09de4a99271acac74d2acb3559a77de77a366b34a91e99e8822667", size = 102812, upload-time = "2025-03-31T21:23:49.16Z" }, + { url = "https://files.pythonhosted.org/packages/cb/50/718ca7b03e4b89b18cdf99cc3038050105b0acbf9b612c23cd513093c6de/ckzg-2.1.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42673c1d007372a4e8b48f6ef8f0ce31a9688a463317a98539757d1e2fb1ecc7", size = 111327, upload-time = "2025-03-31T21:23:50.126Z" }, + { url = "https://files.pythonhosted.org/packages/29/c5/80e5a0c6967d02d801150104320484a258e5a49bd191e198643e74039320/ckzg-2.1.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:57a7dc41ec6b69c1d9117eb61cf001295e6b4f67a736020442e71fb4367fb1a5", size = 98847, upload-time = "2025-03-31T21:23:51.084Z" }, ] [[package]] @@ -363,18 +363,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342 } +sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342, upload-time = "2025-05-20T23:19:49.832Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b", size = 102215 }, + { url = "https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b", size = 102215, upload-time = "2025-05-20T23:19:47.796Z" }, ] [[package]] name = "colorama" version = "0.4.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] [[package]] @@ -384,78 +384,78 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "toolz" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a7/f9/3243eed3a6545c2a33a21f74f655e3fcb5d2192613cd3db81a93369eb339/cytoolz-1.0.1.tar.gz", hash = "sha256:89cc3161b89e1bb3ed7636f74ed2e55984fd35516904fc878cae216e42b2c7d6", size = 626652 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/d9/f13d66c16cff1fa1cb6c234698029877c456f35f577ef274aba3b86e7c51/cytoolz-1.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cec9af61f71fc3853eb5dca3d42eb07d1f48a4599fa502cbe92adde85f74b042", size = 403515 }, - { url = "https://files.pythonhosted.org/packages/4b/2d/4cdf848a69300c7d44984f2ebbebb3b8576e5449c8dea157298f3bdc4da3/cytoolz-1.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:140bbd649dbda01e91add7642149a5987a7c3ccc251f2263de894b89f50b6608", size = 383936 }, - { url = "https://files.pythonhosted.org/packages/72/a4/ccfdd3f0ed9cc818f734b424261f6018fc61e3ec833bf85225a9aca0d994/cytoolz-1.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e90124bdc42ff58b88cdea1d24a6bc5f776414a314cc4d94f25c88badb3a16d1", size = 1934569 }, - { url = "https://files.pythonhosted.org/packages/50/fc/38d5344fa595683ad10dc819cfc1d8b9d2b3391ccf3e8cb7bab4899a01f5/cytoolz-1.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e74801b751e28f7c5cc3ad264c123954a051f546f2fdfe089f5aa7a12ccfa6da", size = 2015129 }, - { url = "https://files.pythonhosted.org/packages/28/29/75261748dc54a20a927f33641f4e9aac674cfc6d3fbd4f332e10d0b37639/cytoolz-1.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:582dad4545ddfb5127494ef23f3fa4855f1673a35d50c66f7638e9fb49805089", size = 2000506 }, - { url = "https://files.pythonhosted.org/packages/00/ae/e4ead004cc2698281d153c4a5388638d67cdb5544d6d6cc1e5b3db2bd2a3/cytoolz-1.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd7bd0618e16efe03bd12f19c2a26a27e6e6b75d7105adb7be1cd2a53fa755d8", size = 1957537 }, - { url = "https://files.pythonhosted.org/packages/4a/ff/4f3aa07f4f47701f7f63df60ce0a5669fa09c256c3d4a33503a9414ea5cc/cytoolz-1.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d74cca6acf1c4af58b2e4a89cc565ed61c5e201de2e434748c93e5a0f5c541a5", size = 1863331 }, - { url = "https://files.pythonhosted.org/packages/a2/29/654f57f2a9b8e9765a4ab876765f64f94530b61fc6471a07feea42ece6d4/cytoolz-1.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:823a3763828d8d457f542b2a45d75d6b4ced5e470b5c7cf2ed66a02f508ed442", size = 1849938 }, - { url = "https://files.pythonhosted.org/packages/bc/7b/11f457db6b291060a98315ab2c7198077d8bddeeebe5f7126d9dad98cc54/cytoolz-1.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:51633a14e6844c61db1d68c1ffd077cf949f5c99c60ed5f1e265b9e2966f1b52", size = 1852345 }, - { url = "https://files.pythonhosted.org/packages/6b/92/0dccc96ce0323be236d404f5084479b79b747fa0e74e43a270e95868b5f9/cytoolz-1.0.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f3ec9b01c45348f1d0d712507d54c2bfd69c62fbd7c9ef555c9d8298693c2432", size = 1989877 }, - { url = "https://files.pythonhosted.org/packages/a3/c8/1c5203a81200bae51aa8f7b5fad613f695bf1afa03f16251ca23ecb2ef9f/cytoolz-1.0.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1855022b712a9c7a5bce354517ab4727a38095f81e2d23d3eabaf1daeb6a3b3c", size = 1994492 }, - { url = "https://files.pythonhosted.org/packages/e2/8a/04bc193c4d7ced8ef6bb62cdcd0bf40b5e5eb26586ed2cfb4433ec7dfd0a/cytoolz-1.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9930f7288c4866a1dc1cc87174f0c6ff4cad1671eb1f6306808aa6c445857d78", size = 1896077 }, - { url = "https://files.pythonhosted.org/packages/21/a5/bee63a58f51d2c74856db66e6119a014464ff8cb1c9387fa4bd2d94e49b0/cytoolz-1.0.1-cp310-cp310-win32.whl", hash = "sha256:a9baad795d72fadc3445ccd0f122abfdbdf94269157e6d6d4835636dad318804", size = 322135 }, - { url = "https://files.pythonhosted.org/packages/e8/16/7abfb1685e8b7f2838264551ee33651748994813f566ac4c3d737dfe90e5/cytoolz-1.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:ad95b386a84e18e1f6136f6d343d2509d4c3aae9f5a536f3dc96808fcc56a8cf", size = 363599 }, - { url = "https://files.pythonhosted.org/packages/dc/ea/8131ae39119820b8867cddc23716fa9f681f2b3bbce6f693e68dfb36b55b/cytoolz-1.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2d958d4f04d9d7018e5c1850790d9d8e68b31c9a2deebca74b903706fdddd2b6", size = 406162 }, - { url = "https://files.pythonhosted.org/packages/26/18/3d9bd4c146f6ea6e51300c242b20cb416966b21d481dac230e1304f1e54b/cytoolz-1.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0f445b8b731fc0ecb1865b8e68a070084eb95d735d04f5b6c851db2daf3048ab", size = 384961 }, - { url = "https://files.pythonhosted.org/packages/e4/73/9034827907c7f85c7c484c9494e905d022fb8174526004e9ef332570349e/cytoolz-1.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f546a96460a7e28eb2ec439f4664fa646c9b3e51c6ebad9a59d3922bbe65e30", size = 2091698 }, - { url = "https://files.pythonhosted.org/packages/74/af/d5c2733b0fde1a08254ff1a8a8d567874040c9eb1606363cfebc0713c73f/cytoolz-1.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0317681dd065532d21836f860b0563b199ee716f55d0c1f10de3ce7100c78a3b", size = 2188452 }, - { url = "https://files.pythonhosted.org/packages/6a/bb/77c71fa9c217260b4056a732d754748903423c2cdd82a673d6064741e375/cytoolz-1.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0c0ef52febd5a7821a3fd8d10f21d460d1a3d2992f724ba9c91fbd7a96745d41", size = 2174203 }, - { url = "https://files.pythonhosted.org/packages/fc/a9/a5b4a3ff5d22faa1b60293bfe97362e2caf4a830c26d37ab5557f60d04b2/cytoolz-1.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5ebaf419acf2de73b643cf96108702b8aef8e825cf4f63209ceb078d5fbbbfd", size = 2099831 }, - { url = "https://files.pythonhosted.org/packages/35/08/7f6869ea1ff31ce5289a7d58d0e7090acfe7058baa2764473048ff61ea3c/cytoolz-1.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5f7f04eeb4088947585c92d6185a618b25ad4a0f8f66ea30c8db83cf94a425e3", size = 1996744 }, - { url = "https://files.pythonhosted.org/packages/46/b4/9ac424c994b51763fd1bbed62d95f8fba8fa0e45c8c3c583904fdaf8f51d/cytoolz-1.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f61928803bb501c17914b82d457c6f50fe838b173fb40d39c38d5961185bd6c7", size = 2013733 }, - { url = "https://files.pythonhosted.org/packages/3e/99/03009765c4b87d742d5b5a8670abb56a8c7ede033c2cdaa4be8662d3b001/cytoolz-1.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d2960cb4fa01ccb985ad1280db41f90dc97a80b397af970a15d5a5de403c8c61", size = 1994850 }, - { url = "https://files.pythonhosted.org/packages/40/9a/8458af9a5557e177ea42f8cf7e477bede518b0bbef564e28c4151feaa52c/cytoolz-1.0.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b2b407cc3e9defa8df5eb46644f6f136586f70ba49eba96f43de67b9a0984fd3", size = 2155352 }, - { url = "https://files.pythonhosted.org/packages/5e/5c/2a701423e001fcbec288b4f3fc2bf67557d114c2388237fc1ae67e1e2686/cytoolz-1.0.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:8245f929144d4d3bd7b972c9593300195c6cea246b81b4c46053c48b3f044580", size = 2163515 }, - { url = "https://files.pythonhosted.org/packages/36/16/ee2e06e65d9d533bc05cd52a0b355ba9072fc8f60d77289e529c6d2e3750/cytoolz-1.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e37385db03af65763933befe89fa70faf25301effc3b0485fec1c15d4ce4f052", size = 2054431 }, - { url = "https://files.pythonhosted.org/packages/d8/d5/2fac8315f210fa1bc7106e27c19e1211580aa25bb7fa17dfd79505e5baf2/cytoolz-1.0.1-cp311-cp311-win32.whl", hash = "sha256:50f9c530f83e3e574fc95c264c3350adde8145f4f8fc8099f65f00cc595e5ead", size = 322004 }, - { url = "https://files.pythonhosted.org/packages/a9/9e/0b70b641850a95f9ff90adde9d094a4b1d81ec54dadfd97fec0a2aaf440e/cytoolz-1.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:b7f6b617454b4326af7bd3c7c49b0fc80767f134eb9fd6449917a058d17a0e3c", size = 365358 }, - { url = "https://files.pythonhosted.org/packages/d8/e8/218098344ed2cb5f8441fade9b2428e435e7073962374a9c71e59ac141a7/cytoolz-1.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fcb8f7d0d65db1269022e7e0428471edee8c937bc288ebdcb72f13eaa67c2fe4", size = 414121 }, - { url = "https://files.pythonhosted.org/packages/de/27/4d729a5653718109262b758fec1a959aa9facb74c15460d9074dc76d6635/cytoolz-1.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:207d4e4b445e087e65556196ff472ff134370d9a275d591724142e255f384662", size = 390904 }, - { url = "https://files.pythonhosted.org/packages/72/c0/cbabfa788bab9c6038953bf9478adaec06e88903a726946ea7c88092f5c4/cytoolz-1.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21cdf6bac6fd843f3b20280a66fd8df20dea4c58eb7214a2cd8957ec176f0bb3", size = 2090734 }, - { url = "https://files.pythonhosted.org/packages/c3/66/369262c60f9423c2da82a60864a259c852f1aa122aced4acd2c679af58c0/cytoolz-1.0.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a55ec098036c0dea9f3bdc021f8acd9d105a945227d0811589f0573f21c9ce1", size = 2155933 }, - { url = "https://files.pythonhosted.org/packages/aa/4e/ee55186802f8d24b5fbf9a11405ccd1203b30eded07cc17750618219b94e/cytoolz-1.0.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a13ab79ff4ce202e03ab646a2134696988b554b6dc4b71451e948403db1331d8", size = 2171903 }, - { url = "https://files.pythonhosted.org/packages/a1/96/bd1a9f3396e9b7f618db8cd08d15630769ce3c8b7d0534f92cd639c977ae/cytoolz-1.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e2d944799026e1ff08a83241f1027a2d9276c41f7a74224cd98b7df6e03957d", size = 2125270 }, - { url = "https://files.pythonhosted.org/packages/28/48/2a3762873091c88a69e161111cfbc6c222ff145d57ff011a642b169f04f1/cytoolz-1.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88ba85834cd523b91fdf10325e1e6d71c798de36ea9bdc187ca7bd146420de6f", size = 1973967 }, - { url = "https://files.pythonhosted.org/packages/e4/50/500bd69774bdc49a4d78ec8779eb6ac7c1a9d706bfd91cf2a1dba604373a/cytoolz-1.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5a750b1af7e8bf6727f588940b690d69e25dc47cce5ce467925a76561317eaf7", size = 2021695 }, - { url = "https://files.pythonhosted.org/packages/e4/4e/ba5a0ce34869495eb50653de8d676847490cf13a2cac1760fc4d313e78de/cytoolz-1.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:44a71870f7eae31d263d08b87da7c2bf1176f78892ed8bdade2c2850478cb126", size = 2010177 }, - { url = "https://files.pythonhosted.org/packages/87/57/615c630b3089a13adb15351d958d227430cf624f03b1dd39eb52c34c1f59/cytoolz-1.0.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c8231b9abbd8e368e036f4cc2e16902c9482d4cf9e02a6147ed0e9a3cd4a9ab0", size = 2154321 }, - { url = "https://files.pythonhosted.org/packages/7f/0f/fe1aa2d931e3b35ecc05215bd75da945ea7346095b3b6f6027164e602d5a/cytoolz-1.0.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:aa87599ccc755de5a096a4d6c34984de6cd9dc928a0c5eaa7607457317aeaf9b", size = 2188374 }, - { url = "https://files.pythonhosted.org/packages/de/fa/fd363d97a641b6d0e2fd1d5c35b8fd41d9ccaeb4df56302f53bf23a58e3a/cytoolz-1.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:67cd16537df51baabde3baa770ab7b8d16839c4d21219d5b96ac59fb012ebd2d", size = 2077911 }, - { url = "https://files.pythonhosted.org/packages/d9/68/0a22946b98ae5201b54ccb4e651295285c0fb79406022b6ee8b2f791940c/cytoolz-1.0.1-cp312-cp312-win32.whl", hash = "sha256:fb988c333f05ee30ad4693fe4da55d95ec0bb05775d2b60191236493ea2e01f9", size = 321903 }, - { url = "https://files.pythonhosted.org/packages/62/1a/f3903197956055032f8cb297342e2dff07e50f83991aebfe5b4c4fcb55e4/cytoolz-1.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:8f89c48d8e5aec55ffd566a8ec858706d70ed0c6a50228eca30986bfa5b4da8b", size = 364490 }, - { url = "https://files.pythonhosted.org/packages/aa/2e/a9f069db0107749e9e72baf6c21abe3f006841a3bcfdc9b8420e22ef31eb/cytoolz-1.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6944bb93b287032a4c5ca6879b69bcd07df46f3079cf8393958cf0b0454f50c0", size = 407365 }, - { url = "https://files.pythonhosted.org/packages/a9/9b/5e87dd0e31f54c778b4f9f34cc14c1162d3096c8d746b0f8be97d70dd73c/cytoolz-1.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e027260fd2fc5cb041277158ac294fc13dca640714527219f702fb459a59823a", size = 385233 }, - { url = "https://files.pythonhosted.org/packages/63/00/2fd32b16284cdb97cfe092822179bc0c3bcdd5e927dd39f986169a517642/cytoolz-1.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88662c0e07250d26f5af9bc95911e6137e124a5c1ec2ce4a5d74de96718ab242", size = 2062903 }, - { url = "https://files.pythonhosted.org/packages/85/39/b3cbb5a9847ba59584a263772ad4f8ca2dbfd2a0e11efd09211d1219804c/cytoolz-1.0.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:309dffa78b0961b4c0cf55674b828fbbc793cf2d816277a5c8293c0c16155296", size = 2139517 }, - { url = "https://files.pythonhosted.org/packages/ea/39/bfcab4a46d50c467e36fe704f19d8904efead417787806ee210327f68390/cytoolz-1.0.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:edb34246e6eb40343c5860fc51b24937698e4fa1ee415917a73ad772a9a1746b", size = 2154849 }, - { url = "https://files.pythonhosted.org/packages/fd/42/3bc6ee61b0aa47e1cb40819adc1a456d7efa809f0dea9faddacb43fdde8f/cytoolz-1.0.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a54da7a8e4348a18d45d4d5bc84af6c716d7f131113a4f1cc45569d37edff1b", size = 2102302 }, - { url = "https://files.pythonhosted.org/packages/00/66/3f636c6ddea7b18026b90a8c238af472e423b86e427b11df02213689b012/cytoolz-1.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:241c679c3b1913c0f7259cf1d9639bed5084c86d0051641d537a0980548aa266", size = 1960872 }, - { url = "https://files.pythonhosted.org/packages/40/36/cb3b7cdd651007b69f9c48e9d104cec7cb8dc53afa1d6a720e5ad08022fa/cytoolz-1.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5bfc860251a8f280ac79696fc3343cfc3a7c30b94199e0240b6c9e5b6b01a2a5", size = 2014430 }, - { url = "https://files.pythonhosted.org/packages/88/3f/2e9bd2a16cfd269808922147551dcb2d8b68ba54a2c4deca2fa6a6cd0d5f/cytoolz-1.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c8edd1547014050c1bdad3ff85d25c82bd1c2a3c96830c6181521eb78b9a42b3", size = 2003127 }, - { url = "https://files.pythonhosted.org/packages/c4/7d/08604ff940aa784df8343c387fdf2489b948b714a6afb587775ae94da912/cytoolz-1.0.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b349bf6162e8de215403d7f35f8a9b4b1853dc2a48e6e1a609a5b1a16868b296", size = 2142369 }, - { url = "https://files.pythonhosted.org/packages/d2/c6/39919a0645bdbdf720e97cae107f959ea9d1267fbc3b0d94fc6e1d12ac8f/cytoolz-1.0.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:1b18b35256219b6c3dd0fa037741b85d0bea39c552eab0775816e85a52834140", size = 2180427 }, - { url = "https://files.pythonhosted.org/packages/d8/03/dbb9d47556ee54337e7e0ac209d17ceff2d2a197c34de08005abc7a7449b/cytoolz-1.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:738b2350f340ff8af883eb301054eb724997f795d20d90daec7911c389d61581", size = 2069785 }, - { url = "https://files.pythonhosted.org/packages/ea/f8/11bb7b8947002231faae3ec2342df5896afbc19eb783a332cce6d219ff79/cytoolz-1.0.1-cp313-cp313-win32.whl", hash = "sha256:9cbd9c103df54fcca42be55ef40e7baea624ac30ee0b8bf1149f21146d1078d9", size = 320685 }, - { url = "https://files.pythonhosted.org/packages/40/eb/dde173cf2357084ca9423950be1f2f11ab11d65d8bd30165bfb8fd4213e9/cytoolz-1.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:90e577e08d3a4308186d9e1ec06876d4756b1e8164b92971c69739ea17e15297", size = 362898 }, - { url = "https://files.pythonhosted.org/packages/d9/f7/ef2a10daaec5c0f7d781d50758c6187eee484256e356ae8ef178d6c48497/cytoolz-1.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:83d19d55738ad9c60763b94f3f6d3c6e4de979aeb8d76841c1401081e0e58d96", size = 345702 }, - { url = "https://files.pythonhosted.org/packages/c8/14/53c84adddedb67ff1546abb86fea04d26e24298c3ceab8436d20122ed0b9/cytoolz-1.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f112a71fad6ea824578e6393765ce5c054603afe1471a5c753ff6c67fd872d10", size = 385695 }, - { url = "https://files.pythonhosted.org/packages/bd/80/3ae356c5e7b8d7dc7d1adb52f6932fee85cd748ed4e1217c269d2dfd610f/cytoolz-1.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a515df8f8aa6e1eaaf397761a6e4aff2eef73b5f920aedf271416d5471ae5ee", size = 406261 }, - { url = "https://files.pythonhosted.org/packages/0c/31/8e43761ffc82d90bf9cab7e0959712eedcd1e33c211397e143dd42d7af57/cytoolz-1.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:92c398e7b7023460bea2edffe5fcd0a76029580f06c3f6938ac3d198b47156f3", size = 397207 }, - { url = "https://files.pythonhosted.org/packages/d1/b9/fe9da37090b6444c65f848a83e390f87d8cb43d6a4df46de1556ad7e5ceb/cytoolz-1.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3237e56211e03b13df47435b2369f5df281e02b04ad80a948ebd199b7bc10a47", size = 343358 }, +sdist = { url = "https://files.pythonhosted.org/packages/a7/f9/3243eed3a6545c2a33a21f74f655e3fcb5d2192613cd3db81a93369eb339/cytoolz-1.0.1.tar.gz", hash = "sha256:89cc3161b89e1bb3ed7636f74ed2e55984fd35516904fc878cae216e42b2c7d6", size = 626652, upload-time = "2024-12-13T05:47:36.672Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/d9/f13d66c16cff1fa1cb6c234698029877c456f35f577ef274aba3b86e7c51/cytoolz-1.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cec9af61f71fc3853eb5dca3d42eb07d1f48a4599fa502cbe92adde85f74b042", size = 403515, upload-time = "2024-12-13T05:44:27.845Z" }, + { url = "https://files.pythonhosted.org/packages/4b/2d/4cdf848a69300c7d44984f2ebbebb3b8576e5449c8dea157298f3bdc4da3/cytoolz-1.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:140bbd649dbda01e91add7642149a5987a7c3ccc251f2263de894b89f50b6608", size = 383936, upload-time = "2024-12-13T05:44:29.5Z" }, + { url = "https://files.pythonhosted.org/packages/72/a4/ccfdd3f0ed9cc818f734b424261f6018fc61e3ec833bf85225a9aca0d994/cytoolz-1.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e90124bdc42ff58b88cdea1d24a6bc5f776414a314cc4d94f25c88badb3a16d1", size = 1934569, upload-time = "2024-12-13T05:44:30.799Z" }, + { url = "https://files.pythonhosted.org/packages/50/fc/38d5344fa595683ad10dc819cfc1d8b9d2b3391ccf3e8cb7bab4899a01f5/cytoolz-1.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e74801b751e28f7c5cc3ad264c123954a051f546f2fdfe089f5aa7a12ccfa6da", size = 2015129, upload-time = "2024-12-13T05:44:32.297Z" }, + { url = "https://files.pythonhosted.org/packages/28/29/75261748dc54a20a927f33641f4e9aac674cfc6d3fbd4f332e10d0b37639/cytoolz-1.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:582dad4545ddfb5127494ef23f3fa4855f1673a35d50c66f7638e9fb49805089", size = 2000506, upload-time = "2024-12-13T05:44:34.403Z" }, + { url = "https://files.pythonhosted.org/packages/00/ae/e4ead004cc2698281d153c4a5388638d67cdb5544d6d6cc1e5b3db2bd2a3/cytoolz-1.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd7bd0618e16efe03bd12f19c2a26a27e6e6b75d7105adb7be1cd2a53fa755d8", size = 1957537, upload-time = "2024-12-13T05:44:39.499Z" }, + { url = "https://files.pythonhosted.org/packages/4a/ff/4f3aa07f4f47701f7f63df60ce0a5669fa09c256c3d4a33503a9414ea5cc/cytoolz-1.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d74cca6acf1c4af58b2e4a89cc565ed61c5e201de2e434748c93e5a0f5c541a5", size = 1863331, upload-time = "2024-12-13T05:44:42.61Z" }, + { url = "https://files.pythonhosted.org/packages/a2/29/654f57f2a9b8e9765a4ab876765f64f94530b61fc6471a07feea42ece6d4/cytoolz-1.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:823a3763828d8d457f542b2a45d75d6b4ced5e470b5c7cf2ed66a02f508ed442", size = 1849938, upload-time = "2024-12-13T05:44:45.324Z" }, + { url = "https://files.pythonhosted.org/packages/bc/7b/11f457db6b291060a98315ab2c7198077d8bddeeebe5f7126d9dad98cc54/cytoolz-1.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:51633a14e6844c61db1d68c1ffd077cf949f5c99c60ed5f1e265b9e2966f1b52", size = 1852345, upload-time = "2024-12-13T05:44:47.994Z" }, + { url = "https://files.pythonhosted.org/packages/6b/92/0dccc96ce0323be236d404f5084479b79b747fa0e74e43a270e95868b5f9/cytoolz-1.0.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f3ec9b01c45348f1d0d712507d54c2bfd69c62fbd7c9ef555c9d8298693c2432", size = 1989877, upload-time = "2024-12-13T05:44:51.514Z" }, + { url = "https://files.pythonhosted.org/packages/a3/c8/1c5203a81200bae51aa8f7b5fad613f695bf1afa03f16251ca23ecb2ef9f/cytoolz-1.0.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1855022b712a9c7a5bce354517ab4727a38095f81e2d23d3eabaf1daeb6a3b3c", size = 1994492, upload-time = "2024-12-13T05:44:52.922Z" }, + { url = "https://files.pythonhosted.org/packages/e2/8a/04bc193c4d7ced8ef6bb62cdcd0bf40b5e5eb26586ed2cfb4433ec7dfd0a/cytoolz-1.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9930f7288c4866a1dc1cc87174f0c6ff4cad1671eb1f6306808aa6c445857d78", size = 1896077, upload-time = "2024-12-13T05:44:56.118Z" }, + { url = "https://files.pythonhosted.org/packages/21/a5/bee63a58f51d2c74856db66e6119a014464ff8cb1c9387fa4bd2d94e49b0/cytoolz-1.0.1-cp310-cp310-win32.whl", hash = "sha256:a9baad795d72fadc3445ccd0f122abfdbdf94269157e6d6d4835636dad318804", size = 322135, upload-time = "2024-12-13T05:44:57.695Z" }, + { url = "https://files.pythonhosted.org/packages/e8/16/7abfb1685e8b7f2838264551ee33651748994813f566ac4c3d737dfe90e5/cytoolz-1.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:ad95b386a84e18e1f6136f6d343d2509d4c3aae9f5a536f3dc96808fcc56a8cf", size = 363599, upload-time = "2024-12-13T05:44:58.875Z" }, + { url = "https://files.pythonhosted.org/packages/dc/ea/8131ae39119820b8867cddc23716fa9f681f2b3bbce6f693e68dfb36b55b/cytoolz-1.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2d958d4f04d9d7018e5c1850790d9d8e68b31c9a2deebca74b903706fdddd2b6", size = 406162, upload-time = "2024-12-13T05:45:01.196Z" }, + { url = "https://files.pythonhosted.org/packages/26/18/3d9bd4c146f6ea6e51300c242b20cb416966b21d481dac230e1304f1e54b/cytoolz-1.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0f445b8b731fc0ecb1865b8e68a070084eb95d735d04f5b6c851db2daf3048ab", size = 384961, upload-time = "2024-12-13T05:45:02.387Z" }, + { url = "https://files.pythonhosted.org/packages/e4/73/9034827907c7f85c7c484c9494e905d022fb8174526004e9ef332570349e/cytoolz-1.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f546a96460a7e28eb2ec439f4664fa646c9b3e51c6ebad9a59d3922bbe65e30", size = 2091698, upload-time = "2024-12-13T05:45:04.353Z" }, + { url = "https://files.pythonhosted.org/packages/74/af/d5c2733b0fde1a08254ff1a8a8d567874040c9eb1606363cfebc0713c73f/cytoolz-1.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0317681dd065532d21836f860b0563b199ee716f55d0c1f10de3ce7100c78a3b", size = 2188452, upload-time = "2024-12-13T05:45:05.748Z" }, + { url = "https://files.pythonhosted.org/packages/6a/bb/77c71fa9c217260b4056a732d754748903423c2cdd82a673d6064741e375/cytoolz-1.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0c0ef52febd5a7821a3fd8d10f21d460d1a3d2992f724ba9c91fbd7a96745d41", size = 2174203, upload-time = "2024-12-13T05:45:07.777Z" }, + { url = "https://files.pythonhosted.org/packages/fc/a9/a5b4a3ff5d22faa1b60293bfe97362e2caf4a830c26d37ab5557f60d04b2/cytoolz-1.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5ebaf419acf2de73b643cf96108702b8aef8e825cf4f63209ceb078d5fbbbfd", size = 2099831, upload-time = "2024-12-13T05:45:11.477Z" }, + { url = "https://files.pythonhosted.org/packages/35/08/7f6869ea1ff31ce5289a7d58d0e7090acfe7058baa2764473048ff61ea3c/cytoolz-1.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5f7f04eeb4088947585c92d6185a618b25ad4a0f8f66ea30c8db83cf94a425e3", size = 1996744, upload-time = "2024-12-13T05:45:14.172Z" }, + { url = "https://files.pythonhosted.org/packages/46/b4/9ac424c994b51763fd1bbed62d95f8fba8fa0e45c8c3c583904fdaf8f51d/cytoolz-1.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f61928803bb501c17914b82d457c6f50fe838b173fb40d39c38d5961185bd6c7", size = 2013733, upload-time = "2024-12-13T05:45:16.912Z" }, + { url = "https://files.pythonhosted.org/packages/3e/99/03009765c4b87d742d5b5a8670abb56a8c7ede033c2cdaa4be8662d3b001/cytoolz-1.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d2960cb4fa01ccb985ad1280db41f90dc97a80b397af970a15d5a5de403c8c61", size = 1994850, upload-time = "2024-12-13T05:45:18.414Z" }, + { url = "https://files.pythonhosted.org/packages/40/9a/8458af9a5557e177ea42f8cf7e477bede518b0bbef564e28c4151feaa52c/cytoolz-1.0.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b2b407cc3e9defa8df5eb46644f6f136586f70ba49eba96f43de67b9a0984fd3", size = 2155352, upload-time = "2024-12-13T05:45:19.763Z" }, + { url = "https://files.pythonhosted.org/packages/5e/5c/2a701423e001fcbec288b4f3fc2bf67557d114c2388237fc1ae67e1e2686/cytoolz-1.0.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:8245f929144d4d3bd7b972c9593300195c6cea246b81b4c46053c48b3f044580", size = 2163515, upload-time = "2024-12-13T05:45:21.08Z" }, + { url = "https://files.pythonhosted.org/packages/36/16/ee2e06e65d9d533bc05cd52a0b355ba9072fc8f60d77289e529c6d2e3750/cytoolz-1.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e37385db03af65763933befe89fa70faf25301effc3b0485fec1c15d4ce4f052", size = 2054431, upload-time = "2024-12-13T05:45:22.521Z" }, + { url = "https://files.pythonhosted.org/packages/d8/d5/2fac8315f210fa1bc7106e27c19e1211580aa25bb7fa17dfd79505e5baf2/cytoolz-1.0.1-cp311-cp311-win32.whl", hash = "sha256:50f9c530f83e3e574fc95c264c3350adde8145f4f8fc8099f65f00cc595e5ead", size = 322004, upload-time = "2024-12-13T05:45:24.048Z" }, + { url = "https://files.pythonhosted.org/packages/a9/9e/0b70b641850a95f9ff90adde9d094a4b1d81ec54dadfd97fec0a2aaf440e/cytoolz-1.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:b7f6b617454b4326af7bd3c7c49b0fc80767f134eb9fd6449917a058d17a0e3c", size = 365358, upload-time = "2024-12-13T05:45:25.383Z" }, + { url = "https://files.pythonhosted.org/packages/d8/e8/218098344ed2cb5f8441fade9b2428e435e7073962374a9c71e59ac141a7/cytoolz-1.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fcb8f7d0d65db1269022e7e0428471edee8c937bc288ebdcb72f13eaa67c2fe4", size = 414121, upload-time = "2024-12-13T05:45:26.588Z" }, + { url = "https://files.pythonhosted.org/packages/de/27/4d729a5653718109262b758fec1a959aa9facb74c15460d9074dc76d6635/cytoolz-1.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:207d4e4b445e087e65556196ff472ff134370d9a275d591724142e255f384662", size = 390904, upload-time = "2024-12-13T05:45:27.718Z" }, + { url = "https://files.pythonhosted.org/packages/72/c0/cbabfa788bab9c6038953bf9478adaec06e88903a726946ea7c88092f5c4/cytoolz-1.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21cdf6bac6fd843f3b20280a66fd8df20dea4c58eb7214a2cd8957ec176f0bb3", size = 2090734, upload-time = "2024-12-13T05:45:30.515Z" }, + { url = "https://files.pythonhosted.org/packages/c3/66/369262c60f9423c2da82a60864a259c852f1aa122aced4acd2c679af58c0/cytoolz-1.0.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a55ec098036c0dea9f3bdc021f8acd9d105a945227d0811589f0573f21c9ce1", size = 2155933, upload-time = "2024-12-13T05:45:32.721Z" }, + { url = "https://files.pythonhosted.org/packages/aa/4e/ee55186802f8d24b5fbf9a11405ccd1203b30eded07cc17750618219b94e/cytoolz-1.0.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a13ab79ff4ce202e03ab646a2134696988b554b6dc4b71451e948403db1331d8", size = 2171903, upload-time = "2024-12-13T05:45:34.205Z" }, + { url = "https://files.pythonhosted.org/packages/a1/96/bd1a9f3396e9b7f618db8cd08d15630769ce3c8b7d0534f92cd639c977ae/cytoolz-1.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e2d944799026e1ff08a83241f1027a2d9276c41f7a74224cd98b7df6e03957d", size = 2125270, upload-time = "2024-12-13T05:45:36.982Z" }, + { url = "https://files.pythonhosted.org/packages/28/48/2a3762873091c88a69e161111cfbc6c222ff145d57ff011a642b169f04f1/cytoolz-1.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88ba85834cd523b91fdf10325e1e6d71c798de36ea9bdc187ca7bd146420de6f", size = 1973967, upload-time = "2024-12-13T05:45:39.505Z" }, + { url = "https://files.pythonhosted.org/packages/e4/50/500bd69774bdc49a4d78ec8779eb6ac7c1a9d706bfd91cf2a1dba604373a/cytoolz-1.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5a750b1af7e8bf6727f588940b690d69e25dc47cce5ce467925a76561317eaf7", size = 2021695, upload-time = "2024-12-13T05:45:40.911Z" }, + { url = "https://files.pythonhosted.org/packages/e4/4e/ba5a0ce34869495eb50653de8d676847490cf13a2cac1760fc4d313e78de/cytoolz-1.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:44a71870f7eae31d263d08b87da7c2bf1176f78892ed8bdade2c2850478cb126", size = 2010177, upload-time = "2024-12-13T05:45:42.48Z" }, + { url = "https://files.pythonhosted.org/packages/87/57/615c630b3089a13adb15351d958d227430cf624f03b1dd39eb52c34c1f59/cytoolz-1.0.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c8231b9abbd8e368e036f4cc2e16902c9482d4cf9e02a6147ed0e9a3cd4a9ab0", size = 2154321, upload-time = "2024-12-13T05:45:43.979Z" }, + { url = "https://files.pythonhosted.org/packages/7f/0f/fe1aa2d931e3b35ecc05215bd75da945ea7346095b3b6f6027164e602d5a/cytoolz-1.0.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:aa87599ccc755de5a096a4d6c34984de6cd9dc928a0c5eaa7607457317aeaf9b", size = 2188374, upload-time = "2024-12-13T05:45:46.783Z" }, + { url = "https://files.pythonhosted.org/packages/de/fa/fd363d97a641b6d0e2fd1d5c35b8fd41d9ccaeb4df56302f53bf23a58e3a/cytoolz-1.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:67cd16537df51baabde3baa770ab7b8d16839c4d21219d5b96ac59fb012ebd2d", size = 2077911, upload-time = "2024-12-13T05:45:48.219Z" }, + { url = "https://files.pythonhosted.org/packages/d9/68/0a22946b98ae5201b54ccb4e651295285c0fb79406022b6ee8b2f791940c/cytoolz-1.0.1-cp312-cp312-win32.whl", hash = "sha256:fb988c333f05ee30ad4693fe4da55d95ec0bb05775d2b60191236493ea2e01f9", size = 321903, upload-time = "2024-12-13T05:45:50.3Z" }, + { url = "https://files.pythonhosted.org/packages/62/1a/f3903197956055032f8cb297342e2dff07e50f83991aebfe5b4c4fcb55e4/cytoolz-1.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:8f89c48d8e5aec55ffd566a8ec858706d70ed0c6a50228eca30986bfa5b4da8b", size = 364490, upload-time = "2024-12-13T05:45:51.494Z" }, + { url = "https://files.pythonhosted.org/packages/aa/2e/a9f069db0107749e9e72baf6c21abe3f006841a3bcfdc9b8420e22ef31eb/cytoolz-1.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6944bb93b287032a4c5ca6879b69bcd07df46f3079cf8393958cf0b0454f50c0", size = 407365, upload-time = "2024-12-13T05:45:52.803Z" }, + { url = "https://files.pythonhosted.org/packages/a9/9b/5e87dd0e31f54c778b4f9f34cc14c1162d3096c8d746b0f8be97d70dd73c/cytoolz-1.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e027260fd2fc5cb041277158ac294fc13dca640714527219f702fb459a59823a", size = 385233, upload-time = "2024-12-13T05:45:53.994Z" }, + { url = "https://files.pythonhosted.org/packages/63/00/2fd32b16284cdb97cfe092822179bc0c3bcdd5e927dd39f986169a517642/cytoolz-1.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88662c0e07250d26f5af9bc95911e6137e124a5c1ec2ce4a5d74de96718ab242", size = 2062903, upload-time = "2024-12-13T05:45:55.202Z" }, + { url = "https://files.pythonhosted.org/packages/85/39/b3cbb5a9847ba59584a263772ad4f8ca2dbfd2a0e11efd09211d1219804c/cytoolz-1.0.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:309dffa78b0961b4c0cf55674b828fbbc793cf2d816277a5c8293c0c16155296", size = 2139517, upload-time = "2024-12-13T05:45:56.804Z" }, + { url = "https://files.pythonhosted.org/packages/ea/39/bfcab4a46d50c467e36fe704f19d8904efead417787806ee210327f68390/cytoolz-1.0.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:edb34246e6eb40343c5860fc51b24937698e4fa1ee415917a73ad772a9a1746b", size = 2154849, upload-time = "2024-12-13T05:45:58.814Z" }, + { url = "https://files.pythonhosted.org/packages/fd/42/3bc6ee61b0aa47e1cb40819adc1a456d7efa809f0dea9faddacb43fdde8f/cytoolz-1.0.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a54da7a8e4348a18d45d4d5bc84af6c716d7f131113a4f1cc45569d37edff1b", size = 2102302, upload-time = "2024-12-13T05:46:00.181Z" }, + { url = "https://files.pythonhosted.org/packages/00/66/3f636c6ddea7b18026b90a8c238af472e423b86e427b11df02213689b012/cytoolz-1.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:241c679c3b1913c0f7259cf1d9639bed5084c86d0051641d537a0980548aa266", size = 1960872, upload-time = "2024-12-13T05:46:01.612Z" }, + { url = "https://files.pythonhosted.org/packages/40/36/cb3b7cdd651007b69f9c48e9d104cec7cb8dc53afa1d6a720e5ad08022fa/cytoolz-1.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5bfc860251a8f280ac79696fc3343cfc3a7c30b94199e0240b6c9e5b6b01a2a5", size = 2014430, upload-time = "2024-12-13T05:46:03.022Z" }, + { url = "https://files.pythonhosted.org/packages/88/3f/2e9bd2a16cfd269808922147551dcb2d8b68ba54a2c4deca2fa6a6cd0d5f/cytoolz-1.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c8edd1547014050c1bdad3ff85d25c82bd1c2a3c96830c6181521eb78b9a42b3", size = 2003127, upload-time = "2024-12-13T05:46:04.401Z" }, + { url = "https://files.pythonhosted.org/packages/c4/7d/08604ff940aa784df8343c387fdf2489b948b714a6afb587775ae94da912/cytoolz-1.0.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b349bf6162e8de215403d7f35f8a9b4b1853dc2a48e6e1a609a5b1a16868b296", size = 2142369, upload-time = "2024-12-13T05:46:06.004Z" }, + { url = "https://files.pythonhosted.org/packages/d2/c6/39919a0645bdbdf720e97cae107f959ea9d1267fbc3b0d94fc6e1d12ac8f/cytoolz-1.0.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:1b18b35256219b6c3dd0fa037741b85d0bea39c552eab0775816e85a52834140", size = 2180427, upload-time = "2024-12-13T05:46:07.526Z" }, + { url = "https://files.pythonhosted.org/packages/d8/03/dbb9d47556ee54337e7e0ac209d17ceff2d2a197c34de08005abc7a7449b/cytoolz-1.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:738b2350f340ff8af883eb301054eb724997f795d20d90daec7911c389d61581", size = 2069785, upload-time = "2024-12-13T05:46:10.122Z" }, + { url = "https://files.pythonhosted.org/packages/ea/f8/11bb7b8947002231faae3ec2342df5896afbc19eb783a332cce6d219ff79/cytoolz-1.0.1-cp313-cp313-win32.whl", hash = "sha256:9cbd9c103df54fcca42be55ef40e7baea624ac30ee0b8bf1149f21146d1078d9", size = 320685, upload-time = "2024-12-13T05:46:11.553Z" }, + { url = "https://files.pythonhosted.org/packages/40/eb/dde173cf2357084ca9423950be1f2f11ab11d65d8bd30165bfb8fd4213e9/cytoolz-1.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:90e577e08d3a4308186d9e1ec06876d4756b1e8164b92971c69739ea17e15297", size = 362898, upload-time = "2024-12-13T05:46:12.771Z" }, + { url = "https://files.pythonhosted.org/packages/d9/f7/ef2a10daaec5c0f7d781d50758c6187eee484256e356ae8ef178d6c48497/cytoolz-1.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:83d19d55738ad9c60763b94f3f6d3c6e4de979aeb8d76841c1401081e0e58d96", size = 345702, upload-time = "2024-12-13T05:47:09.266Z" }, + { url = "https://files.pythonhosted.org/packages/c8/14/53c84adddedb67ff1546abb86fea04d26e24298c3ceab8436d20122ed0b9/cytoolz-1.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f112a71fad6ea824578e6393765ce5c054603afe1471a5c753ff6c67fd872d10", size = 385695, upload-time = "2024-12-13T05:47:11.011Z" }, + { url = "https://files.pythonhosted.org/packages/bd/80/3ae356c5e7b8d7dc7d1adb52f6932fee85cd748ed4e1217c269d2dfd610f/cytoolz-1.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a515df8f8aa6e1eaaf397761a6e4aff2eef73b5f920aedf271416d5471ae5ee", size = 406261, upload-time = "2024-12-13T05:47:12.24Z" }, + { url = "https://files.pythonhosted.org/packages/0c/31/8e43761ffc82d90bf9cab7e0959712eedcd1e33c211397e143dd42d7af57/cytoolz-1.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:92c398e7b7023460bea2edffe5fcd0a76029580f06c3f6938ac3d198b47156f3", size = 397207, upload-time = "2024-12-13T05:47:13.561Z" }, + { url = "https://files.pythonhosted.org/packages/d1/b9/fe9da37090b6444c65f848a83e390f87d8cb43d6a4df46de1556ad7e5ceb/cytoolz-1.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3237e56211e03b13df47435b2369f5df281e02b04ad80a948ebd199b7bc10a47", size = 343358, upload-time = "2024-12-13T05:47:16.291Z" }, ] [[package]] name = "dnspython" version = "2.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b5/4a/263763cb2ba3816dd94b08ad3a33d5fdae34ecb856678773cc40a3605829/dnspython-2.7.0.tar.gz", hash = "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1", size = 345197 } +sdist = { url = "https://files.pythonhosted.org/packages/b5/4a/263763cb2ba3816dd94b08ad3a33d5fdae34ecb856678773cc40a3605829/dnspython-2.7.0.tar.gz", hash = "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1", size = 345197, upload-time = "2024-10-05T20:14:59.362Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/68/1b/e0a87d256e40e8c888847551b20a017a6b98139178505dc7ffb96f04e954/dnspython-2.7.0-py3-none-any.whl", hash = "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86", size = 313632 }, + { url = "https://files.pythonhosted.org/packages/68/1b/e0a87d256e40e8c888847551b20a017a6b98139178505dc7ffb96f04e954/dnspython-2.7.0-py3-none-any.whl", hash = "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86", size = 313632, upload-time = "2024-10-05T20:14:57.687Z" }, ] [[package]] @@ -466,9 +466,9 @@ dependencies = [ { name = "dnspython" }, { name = "idna" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/48/ce/13508a1ec3f8bb981ae4ca79ea40384becc868bfae97fd1c942bb3a001b1/email_validator-2.2.0.tar.gz", hash = "sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7", size = 48967 } +sdist = { url = "https://files.pythonhosted.org/packages/48/ce/13508a1ec3f8bb981ae4ca79ea40384becc868bfae97fd1c942bb3a001b1/email_validator-2.2.0.tar.gz", hash = "sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7", size = 48967, upload-time = "2024-06-20T11:30:30.034Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/ee/bf0adb559ad3c786f12bcbc9296b3f5675f529199bef03e2df281fa1fadb/email_validator-2.2.0-py3-none-any.whl", hash = "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631", size = 33521 }, + { url = "https://files.pythonhosted.org/packages/d7/ee/bf0adb559ad3c786f12bcbc9296b3f5675f529199bef03e2df281fa1fadb/email_validator-2.2.0-py3-none-any.whl", hash = "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631", size = 33521, upload-time = "2024-06-20T11:30:28.248Z" }, ] [[package]] @@ -480,9 +480,9 @@ dependencies = [ { name = "eth-utils" }, { name = "parsimonious" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/00/71/d9e1380bd77fd22f98b534699af564f189b56d539cc2b9dab908d4e4c242/eth_abi-5.2.0.tar.gz", hash = "sha256:178703fa98c07d8eecd5ae569e7e8d159e493ebb6eeb534a8fe973fbc4e40ef0", size = 49797 } +sdist = { url = "https://files.pythonhosted.org/packages/00/71/d9e1380bd77fd22f98b534699af564f189b56d539cc2b9dab908d4e4c242/eth_abi-5.2.0.tar.gz", hash = "sha256:178703fa98c07d8eecd5ae569e7e8d159e493ebb6eeb534a8fe973fbc4e40ef0", size = 49797, upload-time = "2025-01-14T16:29:34.629Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7a/b4/2f3982c4cbcbf5eeb6aec62df1533c0e63c653b3021ff338d44944405676/eth_abi-5.2.0-py3-none-any.whl", hash = "sha256:17abe47560ad753f18054f5b3089fcb588f3e3a092136a416b6c1502cb7e8877", size = 28511 }, + { url = "https://files.pythonhosted.org/packages/7a/b4/2f3982c4cbcbf5eeb6aec62df1533c0e63c653b3021ff338d44944405676/eth_abi-5.2.0-py3-none-any.whl", hash = "sha256:17abe47560ad753f18054f5b3089fcb588f3e3a092136a416b6c1502cb7e8877", size = 28511, upload-time = "2025-01-14T16:29:31.862Z" }, ] [[package]] @@ -501,18 +501,18 @@ dependencies = [ { name = "pydantic" }, { name = "rlp" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/74/cf/20f76a29be97339c969fd765f1237154286a565a1d61be98e76bb7af946a/eth_account-0.13.7.tar.gz", hash = "sha256:5853ecbcbb22e65411176f121f5f24b8afeeaf13492359d254b16d8b18c77a46", size = 935998 } +sdist = { url = "https://files.pythonhosted.org/packages/74/cf/20f76a29be97339c969fd765f1237154286a565a1d61be98e76bb7af946a/eth_account-0.13.7.tar.gz", hash = "sha256:5853ecbcbb22e65411176f121f5f24b8afeeaf13492359d254b16d8b18c77a46", size = 935998, upload-time = "2025-04-21T21:11:21.204Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/46/18/088fb250018cbe665bc2111974301b2d59f294a565aff7564c4df6878da2/eth_account-0.13.7-py3-none-any.whl", hash = "sha256:39727de8c94d004ff61d10da7587509c04d2dc7eac71e04830135300bdfc6d24", size = 587452 }, + { url = "https://files.pythonhosted.org/packages/46/18/088fb250018cbe665bc2111974301b2d59f294a565aff7564c4df6878da2/eth_account-0.13.7-py3-none-any.whl", hash = "sha256:39727de8c94d004ff61d10da7587509c04d2dc7eac71e04830135300bdfc6d24", size = 587452, upload-time = "2025-04-21T21:11:18.346Z" }, ] [[package]] name = "eth-hash" version = "0.7.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/38/577b7bc9380ef9dff0f1dffefe0c9a1ded2385e7a06c306fd95afb6f9451/eth_hash-0.7.1.tar.gz", hash = "sha256:d2411a403a0b0a62e8247b4117932d900ffb4c8c64b15f92620547ca5ce46be5", size = 12227 } +sdist = { url = "https://files.pythonhosted.org/packages/ee/38/577b7bc9380ef9dff0f1dffefe0c9a1ded2385e7a06c306fd95afb6f9451/eth_hash-0.7.1.tar.gz", hash = "sha256:d2411a403a0b0a62e8247b4117932d900ffb4c8c64b15f92620547ca5ce46be5", size = 12227, upload-time = "2025-01-13T21:29:21.765Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/eb/db/f8775490669d28aca24871c67dd56b3e72105cb3bcae9a4ec65dd70859b3/eth_hash-0.7.1-py3-none-any.whl", hash = "sha256:0fb1add2adf99ef28883fd6228eb447ef519ea72933535ad1a0b28c6f65f868a", size = 8028 }, + { url = "https://files.pythonhosted.org/packages/eb/db/f8775490669d28aca24871c67dd56b3e72105cb3bcae9a4ec65dd70859b3/eth_hash-0.7.1-py3-none-any.whl", hash = "sha256:0fb1add2adf99ef28883fd6228eb447ef519ea72933535ad1a0b28c6f65f868a", size = 8028, upload-time = "2025-01-13T21:29:19.365Z" }, ] [package.optional-dependencies] @@ -529,9 +529,9 @@ dependencies = [ { name = "eth-utils" }, { name = "pycryptodome" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/35/66/dd823b1537befefbbff602e2ada88f1477c5b40ec3731e3d9bc676c5f716/eth_keyfile-0.8.1.tar.gz", hash = "sha256:9708bc31f386b52cca0969238ff35b1ac72bd7a7186f2a84b86110d3c973bec1", size = 12267 } +sdist = { url = "https://files.pythonhosted.org/packages/35/66/dd823b1537befefbbff602e2ada88f1477c5b40ec3731e3d9bc676c5f716/eth_keyfile-0.8.1.tar.gz", hash = "sha256:9708bc31f386b52cca0969238ff35b1ac72bd7a7186f2a84b86110d3c973bec1", size = 12267, upload-time = "2024-04-23T20:28:53.862Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/fc/48a586175f847dd9e05e5b8994d2fe8336098781ec2e9836a2ad94280281/eth_keyfile-0.8.1-py3-none-any.whl", hash = "sha256:65387378b82fe7e86d7cb9f8d98e6d639142661b2f6f490629da09fddbef6d64", size = 7510 }, + { url = "https://files.pythonhosted.org/packages/88/fc/48a586175f847dd9e05e5b8994d2fe8336098781ec2e9836a2ad94280281/eth_keyfile-0.8.1-py3-none-any.whl", hash = "sha256:65387378b82fe7e86d7cb9f8d98e6d639142661b2f6f490629da09fddbef6d64", size = 7510, upload-time = "2024-04-23T20:28:51.063Z" }, ] [[package]] @@ -542,9 +542,9 @@ dependencies = [ { name = "eth-typing" }, { name = "eth-utils" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/11/1ed831c50bd74f57829aa06e58bd82a809c37e070ee501c953b9ac1f1552/eth_keys-0.7.0.tar.gz", hash = "sha256:79d24fd876201df67741de3e3fefb3f4dbcbb6ace66e47e6fe662851a4547814", size = 30166 } +sdist = { url = "https://files.pythonhosted.org/packages/58/11/1ed831c50bd74f57829aa06e58bd82a809c37e070ee501c953b9ac1f1552/eth_keys-0.7.0.tar.gz", hash = "sha256:79d24fd876201df67741de3e3fefb3f4dbcbb6ace66e47e6fe662851a4547814", size = 30166, upload-time = "2025-04-07T17:40:21.697Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4d/25/0ae00f2b0095e559d61ad3dc32171bd5a29dfd95ab04b4edd641f7c75f72/eth_keys-0.7.0-py3-none-any.whl", hash = "sha256:b0cdda8ffe8e5ba69c7c5ca33f153828edcace844f67aabd4542d7de38b159cf", size = 20656 }, + { url = "https://files.pythonhosted.org/packages/4d/25/0ae00f2b0095e559d61ad3dc32171bd5a29dfd95ab04b4edd641f7c75f72/eth_keys-0.7.0-py3-none-any.whl", hash = "sha256:b0cdda8ffe8e5ba69c7c5ca33f153828edcace844f67aabd4542d7de38b159cf", size = 20656, upload-time = "2025-04-07T17:40:20.441Z" }, ] [[package]] @@ -557,9 +557,9 @@ dependencies = [ { name = "rlp" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7f/ea/ad39d001fa9fed07fad66edb00af701e29b48be0ed44a3bcf58cb3adf130/eth_rlp-2.2.0.tar.gz", hash = "sha256:5e4b2eb1b8213e303d6a232dfe35ab8c29e2d3051b86e8d359def80cd21db83d", size = 7720 } +sdist = { url = "https://files.pythonhosted.org/packages/7f/ea/ad39d001fa9fed07fad66edb00af701e29b48be0ed44a3bcf58cb3adf130/eth_rlp-2.2.0.tar.gz", hash = "sha256:5e4b2eb1b8213e303d6a232dfe35ab8c29e2d3051b86e8d359def80cd21db83d", size = 7720, upload-time = "2025-02-04T21:51:08.134Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/99/3b/57efe2bc2df0980680d57c01a36516cd3171d2319ceb30e675de19fc2cc5/eth_rlp-2.2.0-py3-none-any.whl", hash = "sha256:5692d595a741fbaef1203db6a2fedffbd2506d31455a6ad378c8449ee5985c47", size = 4446 }, + { url = "https://files.pythonhosted.org/packages/99/3b/57efe2bc2df0980680d57c01a36516cd3171d2319ceb30e675de19fc2cc5/eth_rlp-2.2.0-py3-none-any.whl", hash = "sha256:5692d595a741fbaef1203db6a2fedffbd2506d31455a6ad378c8449ee5985c47", size = 4446, upload-time = "2025-02-04T21:51:05.823Z" }, ] [[package]] @@ -569,9 +569,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/60/54/62aa24b9cc708f06316167ee71c362779c8ed21fc8234a5cd94a8f53b623/eth_typing-5.2.1.tar.gz", hash = "sha256:7557300dbf02a93c70fa44af352b5c4a58f94e997a0fd6797fb7d1c29d9538ee", size = 21806 } +sdist = { url = "https://files.pythonhosted.org/packages/60/54/62aa24b9cc708f06316167ee71c362779c8ed21fc8234a5cd94a8f53b623/eth_typing-5.2.1.tar.gz", hash = "sha256:7557300dbf02a93c70fa44af352b5c4a58f94e997a0fd6797fb7d1c29d9538ee", size = 21806, upload-time = "2025-04-14T20:39:28.217Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/30/72/c370bbe4c53da7bf998d3523f5a0f38867654923a82192df88d0705013d3/eth_typing-5.2.1-py3-none-any.whl", hash = "sha256:b0c2812ff978267563b80e9d701f487dd926f1d376d674f3b535cfe28b665d3d", size = 19163 }, + { url = "https://files.pythonhosted.org/packages/30/72/c370bbe4c53da7bf998d3523f5a0f38867654923a82192df88d0705013d3/eth_typing-5.2.1-py3-none-any.whl", hash = "sha256:b0c2812ff978267563b80e9d701f487dd926f1d376d674f3b535cfe28b665d3d", size = 19163, upload-time = "2025-04-14T20:39:26.571Z" }, ] [[package]] @@ -585,9 +585,9 @@ dependencies = [ { name = "pydantic" }, { name = "toolz", marker = "implementation_name == 'pypy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0d/49/bee95f16d2ef068097afeeffbd6c67738107001ee57ad7bcdd4fc4d3c6a7/eth_utils-5.3.0.tar.gz", hash = "sha256:1f096867ac6be895f456fa3acb26e9573ae66e753abad9208f316d24d6178156", size = 123753 } +sdist = { url = "https://files.pythonhosted.org/packages/0d/49/bee95f16d2ef068097afeeffbd6c67738107001ee57ad7bcdd4fc4d3c6a7/eth_utils-5.3.0.tar.gz", hash = "sha256:1f096867ac6be895f456fa3acb26e9573ae66e753abad9208f316d24d6178156", size = 123753, upload-time = "2025-04-14T19:35:56.431Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c4/c6/0417a92e6a3fc9b85f5a8380d9f9d43b69ba836a90e45f79f9ae74d41e53/eth_utils-5.3.0-py3-none-any.whl", hash = "sha256:ac184883ab299d923428bbe25dae5e356979a3993e0ef695a864db0a20bc262d", size = 102531 }, + { url = "https://files.pythonhosted.org/packages/c4/c6/0417a92e6a3fc9b85f5a8380d9f9d43b69ba836a90e45f79f9ae74d41e53/eth_utils-5.3.0-py3-none-any.whl", hash = "sha256:ac184883ab299d923428bbe25dae5e356979a3993e0ef695a864db0a20bc262d", size = 102531, upload-time = "2025-04-14T19:35:55.176Z" }, ] [[package]] @@ -597,9 +597,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749 } +sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", size = 16674 }, + { url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", size = 16674, upload-time = "2025-05-10T17:42:49.33Z" }, ] [[package]] @@ -611,9 +611,9 @@ dependencies = [ { name = "starlette" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f4/55/ae499352d82338331ca1e28c7f4a63bfd09479b16395dce38cf50a39e2c2/fastapi-0.115.12.tar.gz", hash = "sha256:1e2c2a2646905f9e83d32f04a3f86aff4a286669c6c950ca95b5fd68c2602681", size = 295236 } +sdist = { url = "https://files.pythonhosted.org/packages/f4/55/ae499352d82338331ca1e28c7f4a63bfd09479b16395dce38cf50a39e2c2/fastapi-0.115.12.tar.gz", hash = "sha256:1e2c2a2646905f9e83d32f04a3f86aff4a286669c6c950ca95b5fd68c2602681", size = 295236, upload-time = "2025-03-23T22:55:43.822Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/50/b3/b51f09c2ba432a576fe63758bddc81f78f0c6309d9e5c10d194313bf021e/fastapi-0.115.12-py3-none-any.whl", hash = "sha256:e94613d6c05e27be7ffebdd6ea5f388112e5e430c8f7d6494a9d1d88d43e814d", size = 95164 }, + { url = "https://files.pythonhosted.org/packages/50/b3/b51f09c2ba432a576fe63758bddc81f78f0c6309d9e5c10d194313bf021e/fastapi-0.115.12-py3-none-any.whl", hash = "sha256:e94613d6c05e27be7ffebdd6ea5f388112e5e430c8f7d6494a9d1d88d43e814d", size = 95164, upload-time = "2025-03-23T22:55:42.101Z" }, ] [package.optional-dependencies] @@ -635,9 +635,9 @@ dependencies = [ { name = "typer" }, { name = "uvicorn", extra = ["standard"] }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fe/73/82a5831fbbf8ed75905bacf5b2d9d3dfd6f04d6968b29fe6f72a5ae9ceb1/fastapi_cli-0.0.7.tar.gz", hash = "sha256:02b3b65956f526412515907a0793c9094abd4bfb5457b389f645b0ea6ba3605e", size = 16753 } +sdist = { url = "https://files.pythonhosted.org/packages/fe/73/82a5831fbbf8ed75905bacf5b2d9d3dfd6f04d6968b29fe6f72a5ae9ceb1/fastapi_cli-0.0.7.tar.gz", hash = "sha256:02b3b65956f526412515907a0793c9094abd4bfb5457b389f645b0ea6ba3605e", size = 16753, upload-time = "2024-12-15T14:28:10.028Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a1/e6/5daefc851b514ce2287d8f5d358ae4341089185f78f3217a69d0ce3a390c/fastapi_cli-0.0.7-py3-none-any.whl", hash = "sha256:d549368ff584b2804336c61f192d86ddea080c11255f375959627911944804f4", size = 10705 }, + { url = "https://files.pythonhosted.org/packages/a1/e6/5daefc851b514ce2287d8f5d358ae4341089185f78f3217a69d0ce3a390c/fastapi_cli-0.0.7-py3-none-any.whl", hash = "sha256:d549368ff584b2804336c61f192d86ddea080c11255f375959627911944804f4", size = 10705, upload-time = "2024-12-15T14:28:06.18Z" }, ] [package.optional-dependencies] @@ -657,121 +657,121 @@ dependencies = [ { name = "markupsafe" }, { name = "werkzeug" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c0/de/e47735752347f4128bcf354e0da07ef311a78244eba9e3dc1d4a5ab21a98/flask-3.1.1.tar.gz", hash = "sha256:284c7b8f2f58cb737f0cf1c30fd7eaf0ccfcde196099d24ecede3fc2005aa59e", size = 753440 } +sdist = { url = "https://files.pythonhosted.org/packages/c0/de/e47735752347f4128bcf354e0da07ef311a78244eba9e3dc1d4a5ab21a98/flask-3.1.1.tar.gz", hash = "sha256:284c7b8f2f58cb737f0cf1c30fd7eaf0ccfcde196099d24ecede3fc2005aa59e", size = 753440, upload-time = "2025-05-13T15:01:17.447Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/68/9d4508e893976286d2ead7f8f571314af6c2037af34853a30fd769c02e9d/flask-3.1.1-py3-none-any.whl", hash = "sha256:07aae2bb5eaf77993ef57e357491839f5fd9f4dc281593a81a9e4d79a24f295c", size = 103305 }, + { url = "https://files.pythonhosted.org/packages/3d/68/9d4508e893976286d2ead7f8f571314af6c2037af34853a30fd769c02e9d/flask-3.1.1-py3-none-any.whl", hash = "sha256:07aae2bb5eaf77993ef57e357491839f5fd9f4dc281593a81a9e4d79a24f295c", size = 103305, upload-time = "2025-05-13T15:01:15.591Z" }, ] [[package]] name = "frozenlist" version = "1.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/79/b1/b64018016eeb087db503b038296fd782586432b9c077fc5c7839e9cb6ef6/frozenlist-1.7.0.tar.gz", hash = "sha256:2e310d81923c2437ea8670467121cc3e9b0f76d3043cc1d2331d56c7fb7a3a8f", size = 45078 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/af/36/0da0a49409f6b47cc2d060dc8c9040b897b5902a8a4e37d9bc1deb11f680/frozenlist-1.7.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cc4df77d638aa2ed703b878dd093725b72a824c3c546c076e8fdf276f78ee84a", size = 81304 }, - { url = "https://files.pythonhosted.org/packages/77/f0/77c11d13d39513b298e267b22eb6cb559c103d56f155aa9a49097221f0b6/frozenlist-1.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:716a9973a2cc963160394f701964fe25012600f3d311f60c790400b00e568b61", size = 47735 }, - { url = "https://files.pythonhosted.org/packages/37/12/9d07fa18971a44150593de56b2f2947c46604819976784bcf6ea0d5db43b/frozenlist-1.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0fd1bad056a3600047fb9462cff4c5322cebc59ebf5d0a3725e0ee78955001d", size = 46775 }, - { url = "https://files.pythonhosted.org/packages/70/34/f73539227e06288fcd1f8a76853e755b2b48bca6747e99e283111c18bcd4/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3789ebc19cb811163e70fe2bd354cea097254ce6e707ae42e56f45e31e96cb8e", size = 224644 }, - { url = "https://files.pythonhosted.org/packages/fb/68/c1d9c2f4a6e438e14613bad0f2973567586610cc22dcb1e1241da71de9d3/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:af369aa35ee34f132fcfad5be45fbfcde0e3a5f6a1ec0712857f286b7d20cca9", size = 222125 }, - { url = "https://files.pythonhosted.org/packages/b9/d0/98e8f9a515228d708344d7c6986752be3e3192d1795f748c24bcf154ad99/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac64b6478722eeb7a3313d494f8342ef3478dff539d17002f849101b212ef97c", size = 233455 }, - { url = "https://files.pythonhosted.org/packages/79/df/8a11bcec5600557f40338407d3e5bea80376ed1c01a6c0910fcfdc4b8993/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f89f65d85774f1797239693cef07ad4c97fdd0639544bad9ac4b869782eb1981", size = 227339 }, - { url = "https://files.pythonhosted.org/packages/50/82/41cb97d9c9a5ff94438c63cc343eb7980dac4187eb625a51bdfdb7707314/frozenlist-1.7.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1073557c941395fdfcfac13eb2456cb8aad89f9de27bae29fabca8e563b12615", size = 212969 }, - { url = "https://files.pythonhosted.org/packages/13/47/f9179ee5ee4f55629e4f28c660b3fdf2775c8bfde8f9c53f2de2d93f52a9/frozenlist-1.7.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ed8d2fa095aae4bdc7fdd80351009a48d286635edffee66bf865e37a9125c50", size = 222862 }, - { url = "https://files.pythonhosted.org/packages/1a/52/df81e41ec6b953902c8b7e3a83bee48b195cb0e5ec2eabae5d8330c78038/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:24c34bea555fe42d9f928ba0a740c553088500377448febecaa82cc3e88aa1fa", size = 222492 }, - { url = "https://files.pythonhosted.org/packages/84/17/30d6ea87fa95a9408245a948604b82c1a4b8b3e153cea596421a2aef2754/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:69cac419ac6a6baad202c85aaf467b65ac860ac2e7f2ac1686dc40dbb52f6577", size = 238250 }, - { url = "https://files.pythonhosted.org/packages/8f/00/ecbeb51669e3c3df76cf2ddd66ae3e48345ec213a55e3887d216eb4fbab3/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:960d67d0611f4c87da7e2ae2eacf7ea81a5be967861e0c63cf205215afbfac59", size = 218720 }, - { url = "https://files.pythonhosted.org/packages/1a/c0/c224ce0e0eb31cc57f67742071bb470ba8246623c1823a7530be0e76164c/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:41be2964bd4b15bf575e5daee5a5ce7ed3115320fb3c2b71fca05582ffa4dc9e", size = 232585 }, - { url = "https://files.pythonhosted.org/packages/55/3c/34cb694abf532f31f365106deebdeac9e45c19304d83cf7d51ebbb4ca4d1/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:46d84d49e00c9429238a7ce02dc0be8f6d7cd0cd405abd1bebdc991bf27c15bd", size = 234248 }, - { url = "https://files.pythonhosted.org/packages/98/c0/2052d8b6cecda2e70bd81299e3512fa332abb6dcd2969b9c80dfcdddbf75/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:15900082e886edb37480335d9d518cec978afc69ccbc30bd18610b7c1b22a718", size = 221621 }, - { url = "https://files.pythonhosted.org/packages/c5/bf/7dcebae315436903b1d98ffb791a09d674c88480c158aa171958a3ac07f0/frozenlist-1.7.0-cp310-cp310-win32.whl", hash = "sha256:400ddd24ab4e55014bba442d917203c73b2846391dd42ca5e38ff52bb18c3c5e", size = 39578 }, - { url = "https://files.pythonhosted.org/packages/8f/5f/f69818f017fa9a3d24d1ae39763e29b7f60a59e46d5f91b9c6b21622f4cd/frozenlist-1.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:6eb93efb8101ef39d32d50bce242c84bcbddb4f7e9febfa7b524532a239b4464", size = 43830 }, - { url = "https://files.pythonhosted.org/packages/34/7e/803dde33760128acd393a27eb002f2020ddb8d99d30a44bfbaab31c5f08a/frozenlist-1.7.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:aa51e147a66b2d74de1e6e2cf5921890de6b0f4820b257465101d7f37b49fb5a", size = 82251 }, - { url = "https://files.pythonhosted.org/packages/75/a9/9c2c5760b6ba45eae11334db454c189d43d34a4c0b489feb2175e5e64277/frozenlist-1.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9b35db7ce1cd71d36ba24f80f0c9e7cff73a28d7a74e91fe83e23d27c7828750", size = 48183 }, - { url = "https://files.pythonhosted.org/packages/47/be/4038e2d869f8a2da165f35a6befb9158c259819be22eeaf9c9a8f6a87771/frozenlist-1.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:34a69a85e34ff37791e94542065c8416c1afbf820b68f720452f636d5fb990cd", size = 47107 }, - { url = "https://files.pythonhosted.org/packages/79/26/85314b8a83187c76a37183ceed886381a5f992975786f883472fcb6dc5f2/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a646531fa8d82c87fe4bb2e596f23173caec9185bfbca5d583b4ccfb95183e2", size = 237333 }, - { url = "https://files.pythonhosted.org/packages/1f/fd/e5b64f7d2c92a41639ffb2ad44a6a82f347787abc0c7df5f49057cf11770/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:79b2ffbba483f4ed36a0f236ccb85fbb16e670c9238313709638167670ba235f", size = 231724 }, - { url = "https://files.pythonhosted.org/packages/20/fb/03395c0a43a5976af4bf7534759d214405fbbb4c114683f434dfdd3128ef/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a26f205c9ca5829cbf82bb2a84b5c36f7184c4316617d7ef1b271a56720d6b30", size = 245842 }, - { url = "https://files.pythonhosted.org/packages/d0/15/c01c8e1dffdac5d9803507d824f27aed2ba76b6ed0026fab4d9866e82f1f/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bcacfad3185a623fa11ea0e0634aac7b691aa925d50a440f39b458e41c561d98", size = 239767 }, - { url = "https://files.pythonhosted.org/packages/14/99/3f4c6fe882c1f5514b6848aa0a69b20cb5e5d8e8f51a339d48c0e9305ed0/frozenlist-1.7.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:72c1b0fe8fe451b34f12dce46445ddf14bd2a5bcad7e324987194dc8e3a74c86", size = 224130 }, - { url = "https://files.pythonhosted.org/packages/4d/83/220a374bd7b2aeba9d0725130665afe11de347d95c3620b9b82cc2fcab97/frozenlist-1.7.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61d1a5baeaac6c0798ff6edfaeaa00e0e412d49946c53fae8d4b8e8b3566c4ae", size = 235301 }, - { url = "https://files.pythonhosted.org/packages/03/3c/3e3390d75334a063181625343e8daab61b77e1b8214802cc4e8a1bb678fc/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7edf5c043c062462f09b6820de9854bf28cc6cc5b6714b383149745e287181a8", size = 234606 }, - { url = "https://files.pythonhosted.org/packages/23/1e/58232c19608b7a549d72d9903005e2d82488f12554a32de2d5fb59b9b1ba/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:d50ac7627b3a1bd2dcef6f9da89a772694ec04d9a61b66cf87f7d9446b4a0c31", size = 248372 }, - { url = "https://files.pythonhosted.org/packages/c0/a4/e4a567e01702a88a74ce8a324691e62a629bf47d4f8607f24bf1c7216e7f/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ce48b2fece5aeb45265bb7a58259f45027db0abff478e3077e12b05b17fb9da7", size = 229860 }, - { url = "https://files.pythonhosted.org/packages/73/a6/63b3374f7d22268b41a9db73d68a8233afa30ed164c46107b33c4d18ecdd/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:fe2365ae915a1fafd982c146754e1de6ab3478def8a59c86e1f7242d794f97d5", size = 245893 }, - { url = "https://files.pythonhosted.org/packages/6d/eb/d18b3f6e64799a79673c4ba0b45e4cfbe49c240edfd03a68be20002eaeaa/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:45a6f2fdbd10e074e8814eb98b05292f27bad7d1883afbe009d96abdcf3bc898", size = 246323 }, - { url = "https://files.pythonhosted.org/packages/5a/f5/720f3812e3d06cd89a1d5db9ff6450088b8f5c449dae8ffb2971a44da506/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:21884e23cffabb157a9dd7e353779077bf5b8f9a58e9b262c6caad2ef5f80a56", size = 233149 }, - { url = "https://files.pythonhosted.org/packages/69/68/03efbf545e217d5db8446acfd4c447c15b7c8cf4dbd4a58403111df9322d/frozenlist-1.7.0-cp311-cp311-win32.whl", hash = "sha256:284d233a8953d7b24f9159b8a3496fc1ddc00f4db99c324bd5fb5f22d8698ea7", size = 39565 }, - { url = "https://files.pythonhosted.org/packages/58/17/fe61124c5c333ae87f09bb67186d65038834a47d974fc10a5fadb4cc5ae1/frozenlist-1.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:387cbfdcde2f2353f19c2f66bbb52406d06ed77519ac7ee21be0232147c2592d", size = 44019 }, - { url = "https://files.pythonhosted.org/packages/ef/a2/c8131383f1e66adad5f6ecfcce383d584ca94055a34d683bbb24ac5f2f1c/frozenlist-1.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3dbf9952c4bb0e90e98aec1bd992b3318685005702656bc6f67c1a32b76787f2", size = 81424 }, - { url = "https://files.pythonhosted.org/packages/4c/9d/02754159955088cb52567337d1113f945b9e444c4960771ea90eb73de8db/frozenlist-1.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1f5906d3359300b8a9bb194239491122e6cf1444c2efb88865426f170c262cdb", size = 47952 }, - { url = "https://files.pythonhosted.org/packages/01/7a/0046ef1bd6699b40acd2067ed6d6670b4db2f425c56980fa21c982c2a9db/frozenlist-1.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3dabd5a8f84573c8d10d8859a50ea2dec01eea372031929871368c09fa103478", size = 46688 }, - { url = "https://files.pythonhosted.org/packages/d6/a2/a910bafe29c86997363fb4c02069df4ff0b5bc39d33c5198b4e9dd42d8f8/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa57daa5917f1738064f302bf2626281a1cb01920c32f711fbc7bc36111058a8", size = 243084 }, - { url = "https://files.pythonhosted.org/packages/64/3e/5036af9d5031374c64c387469bfcc3af537fc0f5b1187d83a1cf6fab1639/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c193dda2b6d49f4c4398962810fa7d7c78f032bf45572b3e04dd5249dff27e08", size = 233524 }, - { url = "https://files.pythonhosted.org/packages/06/39/6a17b7c107a2887e781a48ecf20ad20f1c39d94b2a548c83615b5b879f28/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe2b675cf0aaa6d61bf8fbffd3c274b3c9b7b1623beb3809df8a81399a4a9c4", size = 248493 }, - { url = "https://files.pythonhosted.org/packages/be/00/711d1337c7327d88c44d91dd0f556a1c47fb99afc060ae0ef66b4d24793d/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8fc5d5cda37f62b262405cf9652cf0856839c4be8ee41be0afe8858f17f4c94b", size = 244116 }, - { url = "https://files.pythonhosted.org/packages/24/fe/74e6ec0639c115df13d5850e75722750adabdc7de24e37e05a40527ca539/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0d5ce521d1dd7d620198829b87ea002956e4319002ef0bc8d3e6d045cb4646e", size = 224557 }, - { url = "https://files.pythonhosted.org/packages/8d/db/48421f62a6f77c553575201e89048e97198046b793f4a089c79a6e3268bd/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:488d0a7d6a0008ca0db273c542098a0fa9e7dfaa7e57f70acef43f32b3f69dca", size = 241820 }, - { url = "https://files.pythonhosted.org/packages/1d/fa/cb4a76bea23047c8462976ea7b7a2bf53997a0ca171302deae9d6dd12096/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:15a7eaba63983d22c54d255b854e8108e7e5f3e89f647fc854bd77a237e767df", size = 236542 }, - { url = "https://files.pythonhosted.org/packages/5d/32/476a4b5cfaa0ec94d3f808f193301debff2ea42288a099afe60757ef6282/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1eaa7e9c6d15df825bf255649e05bd8a74b04a4d2baa1ae46d9c2d00b2ca2cb5", size = 249350 }, - { url = "https://files.pythonhosted.org/packages/8d/ba/9a28042f84a6bf8ea5dbc81cfff8eaef18d78b2a1ad9d51c7bc5b029ad16/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4389e06714cfa9d47ab87f784a7c5be91d3934cd6e9a7b85beef808297cc025", size = 225093 }, - { url = "https://files.pythonhosted.org/packages/bc/29/3a32959e68f9cf000b04e79ba574527c17e8842e38c91d68214a37455786/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:73bd45e1488c40b63fe5a7df892baf9e2a4d4bb6409a2b3b78ac1c6236178e01", size = 245482 }, - { url = "https://files.pythonhosted.org/packages/80/e8/edf2f9e00da553f07f5fa165325cfc302dead715cab6ac8336a5f3d0adc2/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:99886d98e1643269760e5fe0df31e5ae7050788dd288947f7f007209b8c33f08", size = 249590 }, - { url = "https://files.pythonhosted.org/packages/1c/80/9a0eb48b944050f94cc51ee1c413eb14a39543cc4f760ed12657a5a3c45a/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:290a172aae5a4c278c6da8a96222e6337744cd9c77313efe33d5670b9f65fc43", size = 237785 }, - { url = "https://files.pythonhosted.org/packages/f3/74/87601e0fb0369b7a2baf404ea921769c53b7ae00dee7dcfe5162c8c6dbf0/frozenlist-1.7.0-cp312-cp312-win32.whl", hash = "sha256:426c7bc70e07cfebc178bc4c2bf2d861d720c4fff172181eeb4a4c41d4ca2ad3", size = 39487 }, - { url = "https://files.pythonhosted.org/packages/0b/15/c026e9a9fc17585a9d461f65d8593d281fedf55fbf7eb53f16c6df2392f9/frozenlist-1.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:563b72efe5da92e02eb68c59cb37205457c977aa7a449ed1b37e6939e5c47c6a", size = 43874 }, - { url = "https://files.pythonhosted.org/packages/24/90/6b2cebdabdbd50367273c20ff6b57a3dfa89bd0762de02c3a1eb42cb6462/frozenlist-1.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee80eeda5e2a4e660651370ebffd1286542b67e268aa1ac8d6dbe973120ef7ee", size = 79791 }, - { url = "https://files.pythonhosted.org/packages/83/2e/5b70b6a3325363293fe5fc3ae74cdcbc3e996c2a11dde2fd9f1fb0776d19/frozenlist-1.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d1a81c85417b914139e3a9b995d4a1c84559afc839a93cf2cb7f15e6e5f6ed2d", size = 47165 }, - { url = "https://files.pythonhosted.org/packages/f4/25/a0895c99270ca6966110f4ad98e87e5662eab416a17e7fd53c364bf8b954/frozenlist-1.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cbb65198a9132ebc334f237d7b0df163e4de83fb4f2bdfe46c1e654bdb0c5d43", size = 45881 }, - { url = "https://files.pythonhosted.org/packages/19/7c/71bb0bbe0832793c601fff68cd0cf6143753d0c667f9aec93d3c323f4b55/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dab46c723eeb2c255a64f9dc05b8dd601fde66d6b19cdb82b2e09cc6ff8d8b5d", size = 232409 }, - { url = "https://files.pythonhosted.org/packages/c0/45/ed2798718910fe6eb3ba574082aaceff4528e6323f9a8570be0f7028d8e9/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6aeac207a759d0dedd2e40745575ae32ab30926ff4fa49b1635def65806fddee", size = 225132 }, - { url = "https://files.pythonhosted.org/packages/ba/e2/8417ae0f8eacb1d071d4950f32f229aa6bf68ab69aab797b72a07ea68d4f/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bd8c4e58ad14b4fa7802b8be49d47993182fdd4023393899632c88fd8cd994eb", size = 237638 }, - { url = "https://files.pythonhosted.org/packages/f8/b7/2ace5450ce85f2af05a871b8c8719b341294775a0a6c5585d5e6170f2ce7/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04fb24d104f425da3540ed83cbfc31388a586a7696142004c577fa61c6298c3f", size = 233539 }, - { url = "https://files.pythonhosted.org/packages/46/b9/6989292c5539553dba63f3c83dc4598186ab2888f67c0dc1d917e6887db6/frozenlist-1.7.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a5c505156368e4ea6b53b5ac23c92d7edc864537ff911d2fb24c140bb175e60", size = 215646 }, - { url = "https://files.pythonhosted.org/packages/72/31/bc8c5c99c7818293458fe745dab4fd5730ff49697ccc82b554eb69f16a24/frozenlist-1.7.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8bd7eb96a675f18aa5c553eb7ddc24a43c8c18f22e1f9925528128c052cdbe00", size = 232233 }, - { url = "https://files.pythonhosted.org/packages/59/52/460db4d7ba0811b9ccb85af996019f5d70831f2f5f255f7cc61f86199795/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:05579bf020096fe05a764f1f84cd104a12f78eaab68842d036772dc6d4870b4b", size = 227996 }, - { url = "https://files.pythonhosted.org/packages/ba/c9/f4b39e904c03927b7ecf891804fd3b4df3db29b9e487c6418e37988d6e9d/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:376b6222d114e97eeec13d46c486facd41d4f43bab626b7c3f6a8b4e81a5192c", size = 242280 }, - { url = "https://files.pythonhosted.org/packages/b8/33/3f8d6ced42f162d743e3517781566b8481322be321b486d9d262adf70bfb/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0aa7e176ebe115379b5b1c95b4096fb1c17cce0847402e227e712c27bdb5a949", size = 217717 }, - { url = "https://files.pythonhosted.org/packages/3e/e8/ad683e75da6ccef50d0ab0c2b2324b32f84fc88ceee778ed79b8e2d2fe2e/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3fbba20e662b9c2130dc771e332a99eff5da078b2b2648153a40669a6d0e36ca", size = 236644 }, - { url = "https://files.pythonhosted.org/packages/b2/14/8d19ccdd3799310722195a72ac94ddc677541fb4bef4091d8e7775752360/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:f3f4410a0a601d349dd406b5713fec59b4cee7e71678d5b17edda7f4655a940b", size = 238879 }, - { url = "https://files.pythonhosted.org/packages/ce/13/c12bf657494c2fd1079a48b2db49fa4196325909249a52d8f09bc9123fd7/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e2cdfaaec6a2f9327bf43c933c0319a7c429058e8537c508964a133dffee412e", size = 232502 }, - { url = "https://files.pythonhosted.org/packages/d7/8b/e7f9dfde869825489382bc0d512c15e96d3964180c9499efcec72e85db7e/frozenlist-1.7.0-cp313-cp313-win32.whl", hash = "sha256:5fc4df05a6591c7768459caba1b342d9ec23fa16195e744939ba5914596ae3e1", size = 39169 }, - { url = "https://files.pythonhosted.org/packages/35/89/a487a98d94205d85745080a37860ff5744b9820a2c9acbcdd9440bfddf98/frozenlist-1.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:52109052b9791a3e6b5d1b65f4b909703984b770694d3eb64fad124c835d7cba", size = 43219 }, - { url = "https://files.pythonhosted.org/packages/56/d5/5c4cf2319a49eddd9dd7145e66c4866bdc6f3dbc67ca3d59685149c11e0d/frozenlist-1.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a6f86e4193bb0e235ef6ce3dde5cbabed887e0b11f516ce8a0f4d3b33078ec2d", size = 84345 }, - { url = "https://files.pythonhosted.org/packages/a4/7d/ec2c1e1dc16b85bc9d526009961953df9cec8481b6886debb36ec9107799/frozenlist-1.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:82d664628865abeb32d90ae497fb93df398a69bb3434463d172b80fc25b0dd7d", size = 48880 }, - { url = "https://files.pythonhosted.org/packages/69/86/f9596807b03de126e11e7d42ac91e3d0b19a6599c714a1989a4e85eeefc4/frozenlist-1.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:912a7e8375a1c9a68325a902f3953191b7b292aa3c3fb0d71a216221deca460b", size = 48498 }, - { url = "https://files.pythonhosted.org/packages/5e/cb/df6de220f5036001005f2d726b789b2c0b65f2363b104bbc16f5be8084f8/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9537c2777167488d539bc5de2ad262efc44388230e5118868e172dd4a552b146", size = 292296 }, - { url = "https://files.pythonhosted.org/packages/83/1f/de84c642f17c8f851a2905cee2dae401e5e0daca9b5ef121e120e19aa825/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f34560fb1b4c3e30ba35fa9a13894ba39e5acfc5f60f57d8accde65f46cc5e74", size = 273103 }, - { url = "https://files.pythonhosted.org/packages/88/3c/c840bfa474ba3fa13c772b93070893c6e9d5c0350885760376cbe3b6c1b3/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:acd03d224b0175f5a850edc104ac19040d35419eddad04e7cf2d5986d98427f1", size = 292869 }, - { url = "https://files.pythonhosted.org/packages/a6/1c/3efa6e7d5a39a1d5ef0abeb51c48fb657765794a46cf124e5aca2c7a592c/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2038310bc582f3d6a09b3816ab01737d60bf7b1ec70f5356b09e84fb7408ab1", size = 291467 }, - { url = "https://files.pythonhosted.org/packages/4f/00/d5c5e09d4922c395e2f2f6b79b9a20dab4b67daaf78ab92e7729341f61f6/frozenlist-1.7.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8c05e4c8e5f36e5e088caa1bf78a687528f83c043706640a92cb76cd6999384", size = 266028 }, - { url = "https://files.pythonhosted.org/packages/4e/27/72765be905619dfde25a7f33813ac0341eb6b076abede17a2e3fbfade0cb/frozenlist-1.7.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:765bb588c86e47d0b68f23c1bee323d4b703218037765dcf3f25c838c6fecceb", size = 284294 }, - { url = "https://files.pythonhosted.org/packages/88/67/c94103a23001b17808eb7dd1200c156bb69fb68e63fcf0693dde4cd6228c/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:32dc2e08c67d86d0969714dd484fd60ff08ff81d1a1e40a77dd34a387e6ebc0c", size = 281898 }, - { url = "https://files.pythonhosted.org/packages/42/34/a3e2c00c00f9e2a9db5653bca3fec306349e71aff14ae45ecc6d0951dd24/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:c0303e597eb5a5321b4de9c68e9845ac8f290d2ab3f3e2c864437d3c5a30cd65", size = 290465 }, - { url = "https://files.pythonhosted.org/packages/bb/73/f89b7fbce8b0b0c095d82b008afd0590f71ccb3dee6eee41791cf8cd25fd/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:a47f2abb4e29b3a8d0b530f7c3598badc6b134562b1a5caee867f7c62fee51e3", size = 266385 }, - { url = "https://files.pythonhosted.org/packages/cd/45/e365fdb554159462ca12df54bc59bfa7a9a273ecc21e99e72e597564d1ae/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:3d688126c242a6fabbd92e02633414d40f50bb6002fa4cf995a1d18051525657", size = 288771 }, - { url = "https://files.pythonhosted.org/packages/00/11/47b6117002a0e904f004d70ec5194fe9144f117c33c851e3d51c765962d0/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:4e7e9652b3d367c7bd449a727dc79d5043f48b88d0cbfd4f9f1060cf2b414104", size = 288206 }, - { url = "https://files.pythonhosted.org/packages/40/37/5f9f3c3fd7f7746082ec67bcdc204db72dad081f4f83a503d33220a92973/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1a85e345b4c43db8b842cab1feb41be5cc0b10a1830e6295b69d7310f99becaf", size = 282620 }, - { url = "https://files.pythonhosted.org/packages/0b/31/8fbc5af2d183bff20f21aa743b4088eac4445d2bb1cdece449ae80e4e2d1/frozenlist-1.7.0-cp313-cp313t-win32.whl", hash = "sha256:3a14027124ddb70dfcee5148979998066897e79f89f64b13328595c4bdf77c81", size = 43059 }, - { url = "https://files.pythonhosted.org/packages/bb/ed/41956f52105b8dbc26e457c5705340c67c8cc2b79f394b79bffc09d0e938/frozenlist-1.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3bf8010d71d4507775f658e9823210b7427be36625b387221642725b515dcf3e", size = 47516 }, - { url = "https://files.pythonhosted.org/packages/ee/45/b82e3c16be2182bff01179db177fe144d58b5dc787a7d4492c6ed8b9317f/frozenlist-1.7.0-py3-none-any.whl", hash = "sha256:9a5af342e34f7e97caf8c995864c7a396418ae2859cc6fdf1b1073020d516a7e", size = 13106 }, +sdist = { url = "https://files.pythonhosted.org/packages/79/b1/b64018016eeb087db503b038296fd782586432b9c077fc5c7839e9cb6ef6/frozenlist-1.7.0.tar.gz", hash = "sha256:2e310d81923c2437ea8670467121cc3e9b0f76d3043cc1d2331d56c7fb7a3a8f", size = 45078, upload-time = "2025-06-09T23:02:35.538Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/36/0da0a49409f6b47cc2d060dc8c9040b897b5902a8a4e37d9bc1deb11f680/frozenlist-1.7.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cc4df77d638aa2ed703b878dd093725b72a824c3c546c076e8fdf276f78ee84a", size = 81304, upload-time = "2025-06-09T22:59:46.226Z" }, + { url = "https://files.pythonhosted.org/packages/77/f0/77c11d13d39513b298e267b22eb6cb559c103d56f155aa9a49097221f0b6/frozenlist-1.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:716a9973a2cc963160394f701964fe25012600f3d311f60c790400b00e568b61", size = 47735, upload-time = "2025-06-09T22:59:48.133Z" }, + { url = "https://files.pythonhosted.org/packages/37/12/9d07fa18971a44150593de56b2f2947c46604819976784bcf6ea0d5db43b/frozenlist-1.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0fd1bad056a3600047fb9462cff4c5322cebc59ebf5d0a3725e0ee78955001d", size = 46775, upload-time = "2025-06-09T22:59:49.564Z" }, + { url = "https://files.pythonhosted.org/packages/70/34/f73539227e06288fcd1f8a76853e755b2b48bca6747e99e283111c18bcd4/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3789ebc19cb811163e70fe2bd354cea097254ce6e707ae42e56f45e31e96cb8e", size = 224644, upload-time = "2025-06-09T22:59:51.35Z" }, + { url = "https://files.pythonhosted.org/packages/fb/68/c1d9c2f4a6e438e14613bad0f2973567586610cc22dcb1e1241da71de9d3/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:af369aa35ee34f132fcfad5be45fbfcde0e3a5f6a1ec0712857f286b7d20cca9", size = 222125, upload-time = "2025-06-09T22:59:52.884Z" }, + { url = "https://files.pythonhosted.org/packages/b9/d0/98e8f9a515228d708344d7c6986752be3e3192d1795f748c24bcf154ad99/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac64b6478722eeb7a3313d494f8342ef3478dff539d17002f849101b212ef97c", size = 233455, upload-time = "2025-06-09T22:59:54.74Z" }, + { url = "https://files.pythonhosted.org/packages/79/df/8a11bcec5600557f40338407d3e5bea80376ed1c01a6c0910fcfdc4b8993/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f89f65d85774f1797239693cef07ad4c97fdd0639544bad9ac4b869782eb1981", size = 227339, upload-time = "2025-06-09T22:59:56.187Z" }, + { url = "https://files.pythonhosted.org/packages/50/82/41cb97d9c9a5ff94438c63cc343eb7980dac4187eb625a51bdfdb7707314/frozenlist-1.7.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1073557c941395fdfcfac13eb2456cb8aad89f9de27bae29fabca8e563b12615", size = 212969, upload-time = "2025-06-09T22:59:57.604Z" }, + { url = "https://files.pythonhosted.org/packages/13/47/f9179ee5ee4f55629e4f28c660b3fdf2775c8bfde8f9c53f2de2d93f52a9/frozenlist-1.7.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ed8d2fa095aae4bdc7fdd80351009a48d286635edffee66bf865e37a9125c50", size = 222862, upload-time = "2025-06-09T22:59:59.498Z" }, + { url = "https://files.pythonhosted.org/packages/1a/52/df81e41ec6b953902c8b7e3a83bee48b195cb0e5ec2eabae5d8330c78038/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:24c34bea555fe42d9f928ba0a740c553088500377448febecaa82cc3e88aa1fa", size = 222492, upload-time = "2025-06-09T23:00:01.026Z" }, + { url = "https://files.pythonhosted.org/packages/84/17/30d6ea87fa95a9408245a948604b82c1a4b8b3e153cea596421a2aef2754/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:69cac419ac6a6baad202c85aaf467b65ac860ac2e7f2ac1686dc40dbb52f6577", size = 238250, upload-time = "2025-06-09T23:00:03.401Z" }, + { url = "https://files.pythonhosted.org/packages/8f/00/ecbeb51669e3c3df76cf2ddd66ae3e48345ec213a55e3887d216eb4fbab3/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:960d67d0611f4c87da7e2ae2eacf7ea81a5be967861e0c63cf205215afbfac59", size = 218720, upload-time = "2025-06-09T23:00:05.282Z" }, + { url = "https://files.pythonhosted.org/packages/1a/c0/c224ce0e0eb31cc57f67742071bb470ba8246623c1823a7530be0e76164c/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:41be2964bd4b15bf575e5daee5a5ce7ed3115320fb3c2b71fca05582ffa4dc9e", size = 232585, upload-time = "2025-06-09T23:00:07.962Z" }, + { url = "https://files.pythonhosted.org/packages/55/3c/34cb694abf532f31f365106deebdeac9e45c19304d83cf7d51ebbb4ca4d1/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:46d84d49e00c9429238a7ce02dc0be8f6d7cd0cd405abd1bebdc991bf27c15bd", size = 234248, upload-time = "2025-06-09T23:00:09.428Z" }, + { url = "https://files.pythonhosted.org/packages/98/c0/2052d8b6cecda2e70bd81299e3512fa332abb6dcd2969b9c80dfcdddbf75/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:15900082e886edb37480335d9d518cec978afc69ccbc30bd18610b7c1b22a718", size = 221621, upload-time = "2025-06-09T23:00:11.32Z" }, + { url = "https://files.pythonhosted.org/packages/c5/bf/7dcebae315436903b1d98ffb791a09d674c88480c158aa171958a3ac07f0/frozenlist-1.7.0-cp310-cp310-win32.whl", hash = "sha256:400ddd24ab4e55014bba442d917203c73b2846391dd42ca5e38ff52bb18c3c5e", size = 39578, upload-time = "2025-06-09T23:00:13.526Z" }, + { url = "https://files.pythonhosted.org/packages/8f/5f/f69818f017fa9a3d24d1ae39763e29b7f60a59e46d5f91b9c6b21622f4cd/frozenlist-1.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:6eb93efb8101ef39d32d50bce242c84bcbddb4f7e9febfa7b524532a239b4464", size = 43830, upload-time = "2025-06-09T23:00:14.98Z" }, + { url = "https://files.pythonhosted.org/packages/34/7e/803dde33760128acd393a27eb002f2020ddb8d99d30a44bfbaab31c5f08a/frozenlist-1.7.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:aa51e147a66b2d74de1e6e2cf5921890de6b0f4820b257465101d7f37b49fb5a", size = 82251, upload-time = "2025-06-09T23:00:16.279Z" }, + { url = "https://files.pythonhosted.org/packages/75/a9/9c2c5760b6ba45eae11334db454c189d43d34a4c0b489feb2175e5e64277/frozenlist-1.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9b35db7ce1cd71d36ba24f80f0c9e7cff73a28d7a74e91fe83e23d27c7828750", size = 48183, upload-time = "2025-06-09T23:00:17.698Z" }, + { url = "https://files.pythonhosted.org/packages/47/be/4038e2d869f8a2da165f35a6befb9158c259819be22eeaf9c9a8f6a87771/frozenlist-1.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:34a69a85e34ff37791e94542065c8416c1afbf820b68f720452f636d5fb990cd", size = 47107, upload-time = "2025-06-09T23:00:18.952Z" }, + { url = "https://files.pythonhosted.org/packages/79/26/85314b8a83187c76a37183ceed886381a5f992975786f883472fcb6dc5f2/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a646531fa8d82c87fe4bb2e596f23173caec9185bfbca5d583b4ccfb95183e2", size = 237333, upload-time = "2025-06-09T23:00:20.275Z" }, + { url = "https://files.pythonhosted.org/packages/1f/fd/e5b64f7d2c92a41639ffb2ad44a6a82f347787abc0c7df5f49057cf11770/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:79b2ffbba483f4ed36a0f236ccb85fbb16e670c9238313709638167670ba235f", size = 231724, upload-time = "2025-06-09T23:00:21.705Z" }, + { url = "https://files.pythonhosted.org/packages/20/fb/03395c0a43a5976af4bf7534759d214405fbbb4c114683f434dfdd3128ef/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a26f205c9ca5829cbf82bb2a84b5c36f7184c4316617d7ef1b271a56720d6b30", size = 245842, upload-time = "2025-06-09T23:00:23.148Z" }, + { url = "https://files.pythonhosted.org/packages/d0/15/c01c8e1dffdac5d9803507d824f27aed2ba76b6ed0026fab4d9866e82f1f/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bcacfad3185a623fa11ea0e0634aac7b691aa925d50a440f39b458e41c561d98", size = 239767, upload-time = "2025-06-09T23:00:25.103Z" }, + { url = "https://files.pythonhosted.org/packages/14/99/3f4c6fe882c1f5514b6848aa0a69b20cb5e5d8e8f51a339d48c0e9305ed0/frozenlist-1.7.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:72c1b0fe8fe451b34f12dce46445ddf14bd2a5bcad7e324987194dc8e3a74c86", size = 224130, upload-time = "2025-06-09T23:00:27.061Z" }, + { url = "https://files.pythonhosted.org/packages/4d/83/220a374bd7b2aeba9d0725130665afe11de347d95c3620b9b82cc2fcab97/frozenlist-1.7.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61d1a5baeaac6c0798ff6edfaeaa00e0e412d49946c53fae8d4b8e8b3566c4ae", size = 235301, upload-time = "2025-06-09T23:00:29.02Z" }, + { url = "https://files.pythonhosted.org/packages/03/3c/3e3390d75334a063181625343e8daab61b77e1b8214802cc4e8a1bb678fc/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7edf5c043c062462f09b6820de9854bf28cc6cc5b6714b383149745e287181a8", size = 234606, upload-time = "2025-06-09T23:00:30.514Z" }, + { url = "https://files.pythonhosted.org/packages/23/1e/58232c19608b7a549d72d9903005e2d82488f12554a32de2d5fb59b9b1ba/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:d50ac7627b3a1bd2dcef6f9da89a772694ec04d9a61b66cf87f7d9446b4a0c31", size = 248372, upload-time = "2025-06-09T23:00:31.966Z" }, + { url = "https://files.pythonhosted.org/packages/c0/a4/e4a567e01702a88a74ce8a324691e62a629bf47d4f8607f24bf1c7216e7f/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ce48b2fece5aeb45265bb7a58259f45027db0abff478e3077e12b05b17fb9da7", size = 229860, upload-time = "2025-06-09T23:00:33.375Z" }, + { url = "https://files.pythonhosted.org/packages/73/a6/63b3374f7d22268b41a9db73d68a8233afa30ed164c46107b33c4d18ecdd/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:fe2365ae915a1fafd982c146754e1de6ab3478def8a59c86e1f7242d794f97d5", size = 245893, upload-time = "2025-06-09T23:00:35.002Z" }, + { url = "https://files.pythonhosted.org/packages/6d/eb/d18b3f6e64799a79673c4ba0b45e4cfbe49c240edfd03a68be20002eaeaa/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:45a6f2fdbd10e074e8814eb98b05292f27bad7d1883afbe009d96abdcf3bc898", size = 246323, upload-time = "2025-06-09T23:00:36.468Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f5/720f3812e3d06cd89a1d5db9ff6450088b8f5c449dae8ffb2971a44da506/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:21884e23cffabb157a9dd7e353779077bf5b8f9a58e9b262c6caad2ef5f80a56", size = 233149, upload-time = "2025-06-09T23:00:37.963Z" }, + { url = "https://files.pythonhosted.org/packages/69/68/03efbf545e217d5db8446acfd4c447c15b7c8cf4dbd4a58403111df9322d/frozenlist-1.7.0-cp311-cp311-win32.whl", hash = "sha256:284d233a8953d7b24f9159b8a3496fc1ddc00f4db99c324bd5fb5f22d8698ea7", size = 39565, upload-time = "2025-06-09T23:00:39.753Z" }, + { url = "https://files.pythonhosted.org/packages/58/17/fe61124c5c333ae87f09bb67186d65038834a47d974fc10a5fadb4cc5ae1/frozenlist-1.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:387cbfdcde2f2353f19c2f66bbb52406d06ed77519ac7ee21be0232147c2592d", size = 44019, upload-time = "2025-06-09T23:00:40.988Z" }, + { url = "https://files.pythonhosted.org/packages/ef/a2/c8131383f1e66adad5f6ecfcce383d584ca94055a34d683bbb24ac5f2f1c/frozenlist-1.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3dbf9952c4bb0e90e98aec1bd992b3318685005702656bc6f67c1a32b76787f2", size = 81424, upload-time = "2025-06-09T23:00:42.24Z" }, + { url = "https://files.pythonhosted.org/packages/4c/9d/02754159955088cb52567337d1113f945b9e444c4960771ea90eb73de8db/frozenlist-1.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1f5906d3359300b8a9bb194239491122e6cf1444c2efb88865426f170c262cdb", size = 47952, upload-time = "2025-06-09T23:00:43.481Z" }, + { url = "https://files.pythonhosted.org/packages/01/7a/0046ef1bd6699b40acd2067ed6d6670b4db2f425c56980fa21c982c2a9db/frozenlist-1.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3dabd5a8f84573c8d10d8859a50ea2dec01eea372031929871368c09fa103478", size = 46688, upload-time = "2025-06-09T23:00:44.793Z" }, + { url = "https://files.pythonhosted.org/packages/d6/a2/a910bafe29c86997363fb4c02069df4ff0b5bc39d33c5198b4e9dd42d8f8/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa57daa5917f1738064f302bf2626281a1cb01920c32f711fbc7bc36111058a8", size = 243084, upload-time = "2025-06-09T23:00:46.125Z" }, + { url = "https://files.pythonhosted.org/packages/64/3e/5036af9d5031374c64c387469bfcc3af537fc0f5b1187d83a1cf6fab1639/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c193dda2b6d49f4c4398962810fa7d7c78f032bf45572b3e04dd5249dff27e08", size = 233524, upload-time = "2025-06-09T23:00:47.73Z" }, + { url = "https://files.pythonhosted.org/packages/06/39/6a17b7c107a2887e781a48ecf20ad20f1c39d94b2a548c83615b5b879f28/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe2b675cf0aaa6d61bf8fbffd3c274b3c9b7b1623beb3809df8a81399a4a9c4", size = 248493, upload-time = "2025-06-09T23:00:49.742Z" }, + { url = "https://files.pythonhosted.org/packages/be/00/711d1337c7327d88c44d91dd0f556a1c47fb99afc060ae0ef66b4d24793d/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8fc5d5cda37f62b262405cf9652cf0856839c4be8ee41be0afe8858f17f4c94b", size = 244116, upload-time = "2025-06-09T23:00:51.352Z" }, + { url = "https://files.pythonhosted.org/packages/24/fe/74e6ec0639c115df13d5850e75722750adabdc7de24e37e05a40527ca539/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0d5ce521d1dd7d620198829b87ea002956e4319002ef0bc8d3e6d045cb4646e", size = 224557, upload-time = "2025-06-09T23:00:52.855Z" }, + { url = "https://files.pythonhosted.org/packages/8d/db/48421f62a6f77c553575201e89048e97198046b793f4a089c79a6e3268bd/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:488d0a7d6a0008ca0db273c542098a0fa9e7dfaa7e57f70acef43f32b3f69dca", size = 241820, upload-time = "2025-06-09T23:00:54.43Z" }, + { url = "https://files.pythonhosted.org/packages/1d/fa/cb4a76bea23047c8462976ea7b7a2bf53997a0ca171302deae9d6dd12096/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:15a7eaba63983d22c54d255b854e8108e7e5f3e89f647fc854bd77a237e767df", size = 236542, upload-time = "2025-06-09T23:00:56.409Z" }, + { url = "https://files.pythonhosted.org/packages/5d/32/476a4b5cfaa0ec94d3f808f193301debff2ea42288a099afe60757ef6282/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1eaa7e9c6d15df825bf255649e05bd8a74b04a4d2baa1ae46d9c2d00b2ca2cb5", size = 249350, upload-time = "2025-06-09T23:00:58.468Z" }, + { url = "https://files.pythonhosted.org/packages/8d/ba/9a28042f84a6bf8ea5dbc81cfff8eaef18d78b2a1ad9d51c7bc5b029ad16/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4389e06714cfa9d47ab87f784a7c5be91d3934cd6e9a7b85beef808297cc025", size = 225093, upload-time = "2025-06-09T23:01:00.015Z" }, + { url = "https://files.pythonhosted.org/packages/bc/29/3a32959e68f9cf000b04e79ba574527c17e8842e38c91d68214a37455786/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:73bd45e1488c40b63fe5a7df892baf9e2a4d4bb6409a2b3b78ac1c6236178e01", size = 245482, upload-time = "2025-06-09T23:01:01.474Z" }, + { url = "https://files.pythonhosted.org/packages/80/e8/edf2f9e00da553f07f5fa165325cfc302dead715cab6ac8336a5f3d0adc2/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:99886d98e1643269760e5fe0df31e5ae7050788dd288947f7f007209b8c33f08", size = 249590, upload-time = "2025-06-09T23:01:02.961Z" }, + { url = "https://files.pythonhosted.org/packages/1c/80/9a0eb48b944050f94cc51ee1c413eb14a39543cc4f760ed12657a5a3c45a/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:290a172aae5a4c278c6da8a96222e6337744cd9c77313efe33d5670b9f65fc43", size = 237785, upload-time = "2025-06-09T23:01:05.095Z" }, + { url = "https://files.pythonhosted.org/packages/f3/74/87601e0fb0369b7a2baf404ea921769c53b7ae00dee7dcfe5162c8c6dbf0/frozenlist-1.7.0-cp312-cp312-win32.whl", hash = "sha256:426c7bc70e07cfebc178bc4c2bf2d861d720c4fff172181eeb4a4c41d4ca2ad3", size = 39487, upload-time = "2025-06-09T23:01:06.54Z" }, + { url = "https://files.pythonhosted.org/packages/0b/15/c026e9a9fc17585a9d461f65d8593d281fedf55fbf7eb53f16c6df2392f9/frozenlist-1.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:563b72efe5da92e02eb68c59cb37205457c977aa7a449ed1b37e6939e5c47c6a", size = 43874, upload-time = "2025-06-09T23:01:07.752Z" }, + { url = "https://files.pythonhosted.org/packages/24/90/6b2cebdabdbd50367273c20ff6b57a3dfa89bd0762de02c3a1eb42cb6462/frozenlist-1.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee80eeda5e2a4e660651370ebffd1286542b67e268aa1ac8d6dbe973120ef7ee", size = 79791, upload-time = "2025-06-09T23:01:09.368Z" }, + { url = "https://files.pythonhosted.org/packages/83/2e/5b70b6a3325363293fe5fc3ae74cdcbc3e996c2a11dde2fd9f1fb0776d19/frozenlist-1.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d1a81c85417b914139e3a9b995d4a1c84559afc839a93cf2cb7f15e6e5f6ed2d", size = 47165, upload-time = "2025-06-09T23:01:10.653Z" }, + { url = "https://files.pythonhosted.org/packages/f4/25/a0895c99270ca6966110f4ad98e87e5662eab416a17e7fd53c364bf8b954/frozenlist-1.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cbb65198a9132ebc334f237d7b0df163e4de83fb4f2bdfe46c1e654bdb0c5d43", size = 45881, upload-time = "2025-06-09T23:01:12.296Z" }, + { url = "https://files.pythonhosted.org/packages/19/7c/71bb0bbe0832793c601fff68cd0cf6143753d0c667f9aec93d3c323f4b55/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dab46c723eeb2c255a64f9dc05b8dd601fde66d6b19cdb82b2e09cc6ff8d8b5d", size = 232409, upload-time = "2025-06-09T23:01:13.641Z" }, + { url = "https://files.pythonhosted.org/packages/c0/45/ed2798718910fe6eb3ba574082aaceff4528e6323f9a8570be0f7028d8e9/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6aeac207a759d0dedd2e40745575ae32ab30926ff4fa49b1635def65806fddee", size = 225132, upload-time = "2025-06-09T23:01:15.264Z" }, + { url = "https://files.pythonhosted.org/packages/ba/e2/8417ae0f8eacb1d071d4950f32f229aa6bf68ab69aab797b72a07ea68d4f/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bd8c4e58ad14b4fa7802b8be49d47993182fdd4023393899632c88fd8cd994eb", size = 237638, upload-time = "2025-06-09T23:01:16.752Z" }, + { url = "https://files.pythonhosted.org/packages/f8/b7/2ace5450ce85f2af05a871b8c8719b341294775a0a6c5585d5e6170f2ce7/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04fb24d104f425da3540ed83cbfc31388a586a7696142004c577fa61c6298c3f", size = 233539, upload-time = "2025-06-09T23:01:18.202Z" }, + { url = "https://files.pythonhosted.org/packages/46/b9/6989292c5539553dba63f3c83dc4598186ab2888f67c0dc1d917e6887db6/frozenlist-1.7.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a5c505156368e4ea6b53b5ac23c92d7edc864537ff911d2fb24c140bb175e60", size = 215646, upload-time = "2025-06-09T23:01:19.649Z" }, + { url = "https://files.pythonhosted.org/packages/72/31/bc8c5c99c7818293458fe745dab4fd5730ff49697ccc82b554eb69f16a24/frozenlist-1.7.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8bd7eb96a675f18aa5c553eb7ddc24a43c8c18f22e1f9925528128c052cdbe00", size = 232233, upload-time = "2025-06-09T23:01:21.175Z" }, + { url = "https://files.pythonhosted.org/packages/59/52/460db4d7ba0811b9ccb85af996019f5d70831f2f5f255f7cc61f86199795/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:05579bf020096fe05a764f1f84cd104a12f78eaab68842d036772dc6d4870b4b", size = 227996, upload-time = "2025-06-09T23:01:23.098Z" }, + { url = "https://files.pythonhosted.org/packages/ba/c9/f4b39e904c03927b7ecf891804fd3b4df3db29b9e487c6418e37988d6e9d/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:376b6222d114e97eeec13d46c486facd41d4f43bab626b7c3f6a8b4e81a5192c", size = 242280, upload-time = "2025-06-09T23:01:24.808Z" }, + { url = "https://files.pythonhosted.org/packages/b8/33/3f8d6ced42f162d743e3517781566b8481322be321b486d9d262adf70bfb/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0aa7e176ebe115379b5b1c95b4096fb1c17cce0847402e227e712c27bdb5a949", size = 217717, upload-time = "2025-06-09T23:01:26.28Z" }, + { url = "https://files.pythonhosted.org/packages/3e/e8/ad683e75da6ccef50d0ab0c2b2324b32f84fc88ceee778ed79b8e2d2fe2e/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3fbba20e662b9c2130dc771e332a99eff5da078b2b2648153a40669a6d0e36ca", size = 236644, upload-time = "2025-06-09T23:01:27.887Z" }, + { url = "https://files.pythonhosted.org/packages/b2/14/8d19ccdd3799310722195a72ac94ddc677541fb4bef4091d8e7775752360/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:f3f4410a0a601d349dd406b5713fec59b4cee7e71678d5b17edda7f4655a940b", size = 238879, upload-time = "2025-06-09T23:01:29.524Z" }, + { url = "https://files.pythonhosted.org/packages/ce/13/c12bf657494c2fd1079a48b2db49fa4196325909249a52d8f09bc9123fd7/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e2cdfaaec6a2f9327bf43c933c0319a7c429058e8537c508964a133dffee412e", size = 232502, upload-time = "2025-06-09T23:01:31.287Z" }, + { url = "https://files.pythonhosted.org/packages/d7/8b/e7f9dfde869825489382bc0d512c15e96d3964180c9499efcec72e85db7e/frozenlist-1.7.0-cp313-cp313-win32.whl", hash = "sha256:5fc4df05a6591c7768459caba1b342d9ec23fa16195e744939ba5914596ae3e1", size = 39169, upload-time = "2025-06-09T23:01:35.503Z" }, + { url = "https://files.pythonhosted.org/packages/35/89/a487a98d94205d85745080a37860ff5744b9820a2c9acbcdd9440bfddf98/frozenlist-1.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:52109052b9791a3e6b5d1b65f4b909703984b770694d3eb64fad124c835d7cba", size = 43219, upload-time = "2025-06-09T23:01:36.784Z" }, + { url = "https://files.pythonhosted.org/packages/56/d5/5c4cf2319a49eddd9dd7145e66c4866bdc6f3dbc67ca3d59685149c11e0d/frozenlist-1.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a6f86e4193bb0e235ef6ce3dde5cbabed887e0b11f516ce8a0f4d3b33078ec2d", size = 84345, upload-time = "2025-06-09T23:01:38.295Z" }, + { url = "https://files.pythonhosted.org/packages/a4/7d/ec2c1e1dc16b85bc9d526009961953df9cec8481b6886debb36ec9107799/frozenlist-1.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:82d664628865abeb32d90ae497fb93df398a69bb3434463d172b80fc25b0dd7d", size = 48880, upload-time = "2025-06-09T23:01:39.887Z" }, + { url = "https://files.pythonhosted.org/packages/69/86/f9596807b03de126e11e7d42ac91e3d0b19a6599c714a1989a4e85eeefc4/frozenlist-1.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:912a7e8375a1c9a68325a902f3953191b7b292aa3c3fb0d71a216221deca460b", size = 48498, upload-time = "2025-06-09T23:01:41.318Z" }, + { url = "https://files.pythonhosted.org/packages/5e/cb/df6de220f5036001005f2d726b789b2c0b65f2363b104bbc16f5be8084f8/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9537c2777167488d539bc5de2ad262efc44388230e5118868e172dd4a552b146", size = 292296, upload-time = "2025-06-09T23:01:42.685Z" }, + { url = "https://files.pythonhosted.org/packages/83/1f/de84c642f17c8f851a2905cee2dae401e5e0daca9b5ef121e120e19aa825/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f34560fb1b4c3e30ba35fa9a13894ba39e5acfc5f60f57d8accde65f46cc5e74", size = 273103, upload-time = "2025-06-09T23:01:44.166Z" }, + { url = "https://files.pythonhosted.org/packages/88/3c/c840bfa474ba3fa13c772b93070893c6e9d5c0350885760376cbe3b6c1b3/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:acd03d224b0175f5a850edc104ac19040d35419eddad04e7cf2d5986d98427f1", size = 292869, upload-time = "2025-06-09T23:01:45.681Z" }, + { url = "https://files.pythonhosted.org/packages/a6/1c/3efa6e7d5a39a1d5ef0abeb51c48fb657765794a46cf124e5aca2c7a592c/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2038310bc582f3d6a09b3816ab01737d60bf7b1ec70f5356b09e84fb7408ab1", size = 291467, upload-time = "2025-06-09T23:01:47.234Z" }, + { url = "https://files.pythonhosted.org/packages/4f/00/d5c5e09d4922c395e2f2f6b79b9a20dab4b67daaf78ab92e7729341f61f6/frozenlist-1.7.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8c05e4c8e5f36e5e088caa1bf78a687528f83c043706640a92cb76cd6999384", size = 266028, upload-time = "2025-06-09T23:01:48.819Z" }, + { url = "https://files.pythonhosted.org/packages/4e/27/72765be905619dfde25a7f33813ac0341eb6b076abede17a2e3fbfade0cb/frozenlist-1.7.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:765bb588c86e47d0b68f23c1bee323d4b703218037765dcf3f25c838c6fecceb", size = 284294, upload-time = "2025-06-09T23:01:50.394Z" }, + { url = "https://files.pythonhosted.org/packages/88/67/c94103a23001b17808eb7dd1200c156bb69fb68e63fcf0693dde4cd6228c/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:32dc2e08c67d86d0969714dd484fd60ff08ff81d1a1e40a77dd34a387e6ebc0c", size = 281898, upload-time = "2025-06-09T23:01:52.234Z" }, + { url = "https://files.pythonhosted.org/packages/42/34/a3e2c00c00f9e2a9db5653bca3fec306349e71aff14ae45ecc6d0951dd24/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:c0303e597eb5a5321b4de9c68e9845ac8f290d2ab3f3e2c864437d3c5a30cd65", size = 290465, upload-time = "2025-06-09T23:01:53.788Z" }, + { url = "https://files.pythonhosted.org/packages/bb/73/f89b7fbce8b0b0c095d82b008afd0590f71ccb3dee6eee41791cf8cd25fd/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:a47f2abb4e29b3a8d0b530f7c3598badc6b134562b1a5caee867f7c62fee51e3", size = 266385, upload-time = "2025-06-09T23:01:55.769Z" }, + { url = "https://files.pythonhosted.org/packages/cd/45/e365fdb554159462ca12df54bc59bfa7a9a273ecc21e99e72e597564d1ae/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:3d688126c242a6fabbd92e02633414d40f50bb6002fa4cf995a1d18051525657", size = 288771, upload-time = "2025-06-09T23:01:57.4Z" }, + { url = "https://files.pythonhosted.org/packages/00/11/47b6117002a0e904f004d70ec5194fe9144f117c33c851e3d51c765962d0/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:4e7e9652b3d367c7bd449a727dc79d5043f48b88d0cbfd4f9f1060cf2b414104", size = 288206, upload-time = "2025-06-09T23:01:58.936Z" }, + { url = "https://files.pythonhosted.org/packages/40/37/5f9f3c3fd7f7746082ec67bcdc204db72dad081f4f83a503d33220a92973/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1a85e345b4c43db8b842cab1feb41be5cc0b10a1830e6295b69d7310f99becaf", size = 282620, upload-time = "2025-06-09T23:02:00.493Z" }, + { url = "https://files.pythonhosted.org/packages/0b/31/8fbc5af2d183bff20f21aa743b4088eac4445d2bb1cdece449ae80e4e2d1/frozenlist-1.7.0-cp313-cp313t-win32.whl", hash = "sha256:3a14027124ddb70dfcee5148979998066897e79f89f64b13328595c4bdf77c81", size = 43059, upload-time = "2025-06-09T23:02:02.072Z" }, + { url = "https://files.pythonhosted.org/packages/bb/ed/41956f52105b8dbc26e457c5705340c67c8cc2b79f394b79bffc09d0e938/frozenlist-1.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3bf8010d71d4507775f658e9823210b7427be36625b387221642725b515dcf3e", size = 47516, upload-time = "2025-06-09T23:02:03.779Z" }, + { url = "https://files.pythonhosted.org/packages/ee/45/b82e3c16be2182bff01179db177fe144d58b5dc787a7d4492c6ed8b9317f/frozenlist-1.7.0-py3-none-any.whl", hash = "sha256:9a5af342e34f7e97caf8c995864c7a396418ae2859cc6fdf1b1073020d516a7e", size = 13106, upload-time = "2025-06-09T23:02:34.204Z" }, ] [[package]] name = "h11" version = "0.16.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250 } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515 }, + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, ] [[package]] name = "hexbytes" version = "1.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7f/87/adf4635b4b8c050283d74e6db9a81496063229c9263e6acc1903ab79fbec/hexbytes-1.3.1.tar.gz", hash = "sha256:a657eebebdfe27254336f98d8af6e2236f3f83aed164b87466b6cf6c5f5a4765", size = 8633 } +sdist = { url = "https://files.pythonhosted.org/packages/7f/87/adf4635b4b8c050283d74e6db9a81496063229c9263e6acc1903ab79fbec/hexbytes-1.3.1.tar.gz", hash = "sha256:a657eebebdfe27254336f98d8af6e2236f3f83aed164b87466b6cf6c5f5a4765", size = 8633, upload-time = "2025-05-14T16:45:17.5Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8d/e0/3b31492b1c89da3c5a846680517871455b30c54738486fc57ac79a5761bd/hexbytes-1.3.1-py3-none-any.whl", hash = "sha256:da01ff24a1a9a2b1881c4b85f0e9f9b0f51b526b379ffa23832ae7899d29c2c7", size = 5074 }, + { url = "https://files.pythonhosted.org/packages/8d/e0/3b31492b1c89da3c5a846680517871455b30c54738486fc57ac79a5761bd/hexbytes-1.3.1-py3-none-any.whl", hash = "sha256:da01ff24a1a9a2b1881c4b85f0e9f9b0f51b526b379ffa23832ae7899d29c2c7", size = 5074, upload-time = "2025-05-14T16:45:16.179Z" }, ] [[package]] @@ -782,45 +782,45 @@ dependencies = [ { name = "certifi" }, { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484 } +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784 }, + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, ] [[package]] name = "httptools" version = "0.6.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a7/9a/ce5e1f7e131522e6d3426e8e7a490b3a01f39a6696602e1c4f33f9e94277/httptools-0.6.4.tar.gz", hash = "sha256:4e93eee4add6493b59a5c514da98c939b244fce4a0d8879cd3f466562f4b7d5c", size = 240639 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3b/6f/972f8eb0ea7d98a1c6be436e2142d51ad2a64ee18e02b0e7ff1f62171ab1/httptools-0.6.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3c73ce323711a6ffb0d247dcd5a550b8babf0f757e86a52558fe5b86d6fefcc0", size = 198780 }, - { url = "https://files.pythonhosted.org/packages/6a/b0/17c672b4bc5c7ba7f201eada4e96c71d0a59fbc185e60e42580093a86f21/httptools-0.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:345c288418f0944a6fe67be8e6afa9262b18c7626c3ef3c28adc5eabc06a68da", size = 103297 }, - { url = "https://files.pythonhosted.org/packages/92/5e/b4a826fe91971a0b68e8c2bd4e7db3e7519882f5a8ccdb1194be2b3ab98f/httptools-0.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deee0e3343f98ee8047e9f4c5bc7cedbf69f5734454a94c38ee829fb2d5fa3c1", size = 443130 }, - { url = "https://files.pythonhosted.org/packages/b0/51/ce61e531e40289a681a463e1258fa1e05e0be54540e40d91d065a264cd8f/httptools-0.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca80b7485c76f768a3bc83ea58373f8db7b015551117375e4918e2aa77ea9b50", size = 442148 }, - { url = "https://files.pythonhosted.org/packages/ea/9e/270b7d767849b0c96f275c695d27ca76c30671f8eb8cc1bab6ced5c5e1d0/httptools-0.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:90d96a385fa941283ebd231464045187a31ad932ebfa541be8edf5b3c2328959", size = 415949 }, - { url = "https://files.pythonhosted.org/packages/81/86/ced96e3179c48c6f656354e106934e65c8963d48b69be78f355797f0e1b3/httptools-0.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:59e724f8b332319e2875efd360e61ac07f33b492889284a3e05e6d13746876f4", size = 417591 }, - { url = "https://files.pythonhosted.org/packages/75/73/187a3f620ed3175364ddb56847d7a608a6fc42d551e133197098c0143eca/httptools-0.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:c26f313951f6e26147833fc923f78f95604bbec812a43e5ee37f26dc9e5a686c", size = 88344 }, - { url = "https://files.pythonhosted.org/packages/7b/26/bb526d4d14c2774fe07113ca1db7255737ffbb119315839af2065abfdac3/httptools-0.6.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f47f8ed67cc0ff862b84a1189831d1d33c963fb3ce1ee0c65d3b0cbe7b711069", size = 199029 }, - { url = "https://files.pythonhosted.org/packages/a6/17/3e0d3e9b901c732987a45f4f94d4e2c62b89a041d93db89eafb262afd8d5/httptools-0.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0614154d5454c21b6410fdf5262b4a3ddb0f53f1e1721cfd59d55f32138c578a", size = 103492 }, - { url = "https://files.pythonhosted.org/packages/b7/24/0fe235d7b69c42423c7698d086d4db96475f9b50b6ad26a718ef27a0bce6/httptools-0.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8787367fbdfccae38e35abf7641dafc5310310a5987b689f4c32cc8cc3ee975", size = 462891 }, - { url = "https://files.pythonhosted.org/packages/b1/2f/205d1f2a190b72da6ffb5f41a3736c26d6fa7871101212b15e9b5cd8f61d/httptools-0.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40b0f7fe4fd38e6a507bdb751db0379df1e99120c65fbdc8ee6c1d044897a636", size = 459788 }, - { url = "https://files.pythonhosted.org/packages/6e/4c/d09ce0eff09057a206a74575ae8f1e1e2f0364d20e2442224f9e6612c8b9/httptools-0.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:40a5ec98d3f49904b9fe36827dcf1aadfef3b89e2bd05b0e35e94f97c2b14721", size = 433214 }, - { url = "https://files.pythonhosted.org/packages/3e/d2/84c9e23edbccc4a4c6f96a1b8d99dfd2350289e94f00e9ccc7aadde26fb5/httptools-0.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dacdd3d10ea1b4ca9df97a0a303cbacafc04b5cd375fa98732678151643d4988", size = 434120 }, - { url = "https://files.pythonhosted.org/packages/d0/46/4d8e7ba9581416de1c425b8264e2cadd201eb709ec1584c381f3e98f51c1/httptools-0.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:288cd628406cc53f9a541cfaf06041b4c71d751856bab45e3702191f931ccd17", size = 88565 }, - { url = "https://files.pythonhosted.org/packages/bb/0e/d0b71465c66b9185f90a091ab36389a7352985fe857e352801c39d6127c8/httptools-0.6.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:df017d6c780287d5c80601dafa31f17bddb170232d85c066604d8558683711a2", size = 200683 }, - { url = "https://files.pythonhosted.org/packages/e2/b8/412a9bb28d0a8988de3296e01efa0bd62068b33856cdda47fe1b5e890954/httptools-0.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:85071a1e8c2d051b507161f6c3e26155b5c790e4e28d7f236422dbacc2a9cc44", size = 104337 }, - { url = "https://files.pythonhosted.org/packages/9b/01/6fb20be3196ffdc8eeec4e653bc2a275eca7f36634c86302242c4fbb2760/httptools-0.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69422b7f458c5af875922cdb5bd586cc1f1033295aa9ff63ee196a87519ac8e1", size = 508796 }, - { url = "https://files.pythonhosted.org/packages/f7/d8/b644c44acc1368938317d76ac991c9bba1166311880bcc0ac297cb9d6bd7/httptools-0.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16e603a3bff50db08cd578d54f07032ca1631450ceb972c2f834c2b860c28ea2", size = 510837 }, - { url = "https://files.pythonhosted.org/packages/52/d8/254d16a31d543073a0e57f1c329ca7378d8924e7e292eda72d0064987486/httptools-0.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ec4f178901fa1834d4a060320d2f3abc5c9e39766953d038f1458cb885f47e81", size = 485289 }, - { url = "https://files.pythonhosted.org/packages/5f/3c/4aee161b4b7a971660b8be71a92c24d6c64372c1ab3ae7f366b3680df20f/httptools-0.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f9eb89ecf8b290f2e293325c646a211ff1c2493222798bb80a530c5e7502494f", size = 489779 }, - { url = "https://files.pythonhosted.org/packages/12/b7/5cae71a8868e555f3f67a50ee7f673ce36eac970f029c0c5e9d584352961/httptools-0.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:db78cb9ca56b59b016e64b6031eda5653be0589dba2b1b43453f6e8b405a0970", size = 88634 }, - { url = "https://files.pythonhosted.org/packages/94/a3/9fe9ad23fd35f7de6b91eeb60848986058bd8b5a5c1e256f5860a160cc3e/httptools-0.6.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ade273d7e767d5fae13fa637f4d53b6e961fb7fd93c7797562663f0171c26660", size = 197214 }, - { url = "https://files.pythonhosted.org/packages/ea/d9/82d5e68bab783b632023f2fa31db20bebb4e89dfc4d2293945fd68484ee4/httptools-0.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:856f4bc0478ae143bad54a4242fccb1f3f86a6e1be5548fecfd4102061b3a083", size = 102431 }, - { url = "https://files.pythonhosted.org/packages/96/c1/cb499655cbdbfb57b577734fde02f6fa0bbc3fe9fb4d87b742b512908dff/httptools-0.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:322d20ea9cdd1fa98bd6a74b77e2ec5b818abdc3d36695ab402a0de8ef2865a3", size = 473121 }, - { url = "https://files.pythonhosted.org/packages/af/71/ee32fd358f8a3bb199b03261f10921716990808a675d8160b5383487a317/httptools-0.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d87b29bd4486c0093fc64dea80231f7c7f7eb4dc70ae394d70a495ab8436071", size = 473805 }, - { url = "https://files.pythonhosted.org/packages/8a/0a/0d4df132bfca1507114198b766f1737d57580c9ad1cf93c1ff673e3387be/httptools-0.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:342dd6946aa6bda4b8f18c734576106b8a31f2fe31492881a9a160ec84ff4bd5", size = 448858 }, - { url = "https://files.pythonhosted.org/packages/1e/6a/787004fdef2cabea27bad1073bf6a33f2437b4dbd3b6fb4a9d71172b1c7c/httptools-0.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b36913ba52008249223042dca46e69967985fb4051951f94357ea681e1f5dc0", size = 452042 }, - { url = "https://files.pythonhosted.org/packages/4d/dc/7decab5c404d1d2cdc1bb330b1bf70e83d6af0396fd4fc76fc60c0d522bf/httptools-0.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:28908df1b9bb8187393d5b5db91435ccc9c8e891657f9cbb42a2541b44c82fc8", size = 87682 }, +sdist = { url = "https://files.pythonhosted.org/packages/a7/9a/ce5e1f7e131522e6d3426e8e7a490b3a01f39a6696602e1c4f33f9e94277/httptools-0.6.4.tar.gz", hash = "sha256:4e93eee4add6493b59a5c514da98c939b244fce4a0d8879cd3f466562f4b7d5c", size = 240639, upload-time = "2024-10-16T19:45:08.902Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/6f/972f8eb0ea7d98a1c6be436e2142d51ad2a64ee18e02b0e7ff1f62171ab1/httptools-0.6.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3c73ce323711a6ffb0d247dcd5a550b8babf0f757e86a52558fe5b86d6fefcc0", size = 198780, upload-time = "2024-10-16T19:44:06.882Z" }, + { url = "https://files.pythonhosted.org/packages/6a/b0/17c672b4bc5c7ba7f201eada4e96c71d0a59fbc185e60e42580093a86f21/httptools-0.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:345c288418f0944a6fe67be8e6afa9262b18c7626c3ef3c28adc5eabc06a68da", size = 103297, upload-time = "2024-10-16T19:44:08.129Z" }, + { url = "https://files.pythonhosted.org/packages/92/5e/b4a826fe91971a0b68e8c2bd4e7db3e7519882f5a8ccdb1194be2b3ab98f/httptools-0.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deee0e3343f98ee8047e9f4c5bc7cedbf69f5734454a94c38ee829fb2d5fa3c1", size = 443130, upload-time = "2024-10-16T19:44:09.45Z" }, + { url = "https://files.pythonhosted.org/packages/b0/51/ce61e531e40289a681a463e1258fa1e05e0be54540e40d91d065a264cd8f/httptools-0.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca80b7485c76f768a3bc83ea58373f8db7b015551117375e4918e2aa77ea9b50", size = 442148, upload-time = "2024-10-16T19:44:11.539Z" }, + { url = "https://files.pythonhosted.org/packages/ea/9e/270b7d767849b0c96f275c695d27ca76c30671f8eb8cc1bab6ced5c5e1d0/httptools-0.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:90d96a385fa941283ebd231464045187a31ad932ebfa541be8edf5b3c2328959", size = 415949, upload-time = "2024-10-16T19:44:13.388Z" }, + { url = "https://files.pythonhosted.org/packages/81/86/ced96e3179c48c6f656354e106934e65c8963d48b69be78f355797f0e1b3/httptools-0.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:59e724f8b332319e2875efd360e61ac07f33b492889284a3e05e6d13746876f4", size = 417591, upload-time = "2024-10-16T19:44:15.258Z" }, + { url = "https://files.pythonhosted.org/packages/75/73/187a3f620ed3175364ddb56847d7a608a6fc42d551e133197098c0143eca/httptools-0.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:c26f313951f6e26147833fc923f78f95604bbec812a43e5ee37f26dc9e5a686c", size = 88344, upload-time = "2024-10-16T19:44:16.54Z" }, + { url = "https://files.pythonhosted.org/packages/7b/26/bb526d4d14c2774fe07113ca1db7255737ffbb119315839af2065abfdac3/httptools-0.6.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f47f8ed67cc0ff862b84a1189831d1d33c963fb3ce1ee0c65d3b0cbe7b711069", size = 199029, upload-time = "2024-10-16T19:44:18.427Z" }, + { url = "https://files.pythonhosted.org/packages/a6/17/3e0d3e9b901c732987a45f4f94d4e2c62b89a041d93db89eafb262afd8d5/httptools-0.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0614154d5454c21b6410fdf5262b4a3ddb0f53f1e1721cfd59d55f32138c578a", size = 103492, upload-time = "2024-10-16T19:44:19.515Z" }, + { url = "https://files.pythonhosted.org/packages/b7/24/0fe235d7b69c42423c7698d086d4db96475f9b50b6ad26a718ef27a0bce6/httptools-0.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8787367fbdfccae38e35abf7641dafc5310310a5987b689f4c32cc8cc3ee975", size = 462891, upload-time = "2024-10-16T19:44:21.067Z" }, + { url = "https://files.pythonhosted.org/packages/b1/2f/205d1f2a190b72da6ffb5f41a3736c26d6fa7871101212b15e9b5cd8f61d/httptools-0.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40b0f7fe4fd38e6a507bdb751db0379df1e99120c65fbdc8ee6c1d044897a636", size = 459788, upload-time = "2024-10-16T19:44:22.958Z" }, + { url = "https://files.pythonhosted.org/packages/6e/4c/d09ce0eff09057a206a74575ae8f1e1e2f0364d20e2442224f9e6612c8b9/httptools-0.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:40a5ec98d3f49904b9fe36827dcf1aadfef3b89e2bd05b0e35e94f97c2b14721", size = 433214, upload-time = "2024-10-16T19:44:24.513Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d2/84c9e23edbccc4a4c6f96a1b8d99dfd2350289e94f00e9ccc7aadde26fb5/httptools-0.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dacdd3d10ea1b4ca9df97a0a303cbacafc04b5cd375fa98732678151643d4988", size = 434120, upload-time = "2024-10-16T19:44:26.295Z" }, + { url = "https://files.pythonhosted.org/packages/d0/46/4d8e7ba9581416de1c425b8264e2cadd201eb709ec1584c381f3e98f51c1/httptools-0.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:288cd628406cc53f9a541cfaf06041b4c71d751856bab45e3702191f931ccd17", size = 88565, upload-time = "2024-10-16T19:44:29.188Z" }, + { url = "https://files.pythonhosted.org/packages/bb/0e/d0b71465c66b9185f90a091ab36389a7352985fe857e352801c39d6127c8/httptools-0.6.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:df017d6c780287d5c80601dafa31f17bddb170232d85c066604d8558683711a2", size = 200683, upload-time = "2024-10-16T19:44:30.175Z" }, + { url = "https://files.pythonhosted.org/packages/e2/b8/412a9bb28d0a8988de3296e01efa0bd62068b33856cdda47fe1b5e890954/httptools-0.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:85071a1e8c2d051b507161f6c3e26155b5c790e4e28d7f236422dbacc2a9cc44", size = 104337, upload-time = "2024-10-16T19:44:31.786Z" }, + { url = "https://files.pythonhosted.org/packages/9b/01/6fb20be3196ffdc8eeec4e653bc2a275eca7f36634c86302242c4fbb2760/httptools-0.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69422b7f458c5af875922cdb5bd586cc1f1033295aa9ff63ee196a87519ac8e1", size = 508796, upload-time = "2024-10-16T19:44:32.825Z" }, + { url = "https://files.pythonhosted.org/packages/f7/d8/b644c44acc1368938317d76ac991c9bba1166311880bcc0ac297cb9d6bd7/httptools-0.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16e603a3bff50db08cd578d54f07032ca1631450ceb972c2f834c2b860c28ea2", size = 510837, upload-time = "2024-10-16T19:44:33.974Z" }, + { url = "https://files.pythonhosted.org/packages/52/d8/254d16a31d543073a0e57f1c329ca7378d8924e7e292eda72d0064987486/httptools-0.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ec4f178901fa1834d4a060320d2f3abc5c9e39766953d038f1458cb885f47e81", size = 485289, upload-time = "2024-10-16T19:44:35.111Z" }, + { url = "https://files.pythonhosted.org/packages/5f/3c/4aee161b4b7a971660b8be71a92c24d6c64372c1ab3ae7f366b3680df20f/httptools-0.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f9eb89ecf8b290f2e293325c646a211ff1c2493222798bb80a530c5e7502494f", size = 489779, upload-time = "2024-10-16T19:44:36.253Z" }, + { url = "https://files.pythonhosted.org/packages/12/b7/5cae71a8868e555f3f67a50ee7f673ce36eac970f029c0c5e9d584352961/httptools-0.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:db78cb9ca56b59b016e64b6031eda5653be0589dba2b1b43453f6e8b405a0970", size = 88634, upload-time = "2024-10-16T19:44:37.357Z" }, + { url = "https://files.pythonhosted.org/packages/94/a3/9fe9ad23fd35f7de6b91eeb60848986058bd8b5a5c1e256f5860a160cc3e/httptools-0.6.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ade273d7e767d5fae13fa637f4d53b6e961fb7fd93c7797562663f0171c26660", size = 197214, upload-time = "2024-10-16T19:44:38.738Z" }, + { url = "https://files.pythonhosted.org/packages/ea/d9/82d5e68bab783b632023f2fa31db20bebb4e89dfc4d2293945fd68484ee4/httptools-0.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:856f4bc0478ae143bad54a4242fccb1f3f86a6e1be5548fecfd4102061b3a083", size = 102431, upload-time = "2024-10-16T19:44:39.818Z" }, + { url = "https://files.pythonhosted.org/packages/96/c1/cb499655cbdbfb57b577734fde02f6fa0bbc3fe9fb4d87b742b512908dff/httptools-0.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:322d20ea9cdd1fa98bd6a74b77e2ec5b818abdc3d36695ab402a0de8ef2865a3", size = 473121, upload-time = "2024-10-16T19:44:41.189Z" }, + { url = "https://files.pythonhosted.org/packages/af/71/ee32fd358f8a3bb199b03261f10921716990808a675d8160b5383487a317/httptools-0.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d87b29bd4486c0093fc64dea80231f7c7f7eb4dc70ae394d70a495ab8436071", size = 473805, upload-time = "2024-10-16T19:44:42.384Z" }, + { url = "https://files.pythonhosted.org/packages/8a/0a/0d4df132bfca1507114198b766f1737d57580c9ad1cf93c1ff673e3387be/httptools-0.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:342dd6946aa6bda4b8f18c734576106b8a31f2fe31492881a9a160ec84ff4bd5", size = 448858, upload-time = "2024-10-16T19:44:43.959Z" }, + { url = "https://files.pythonhosted.org/packages/1e/6a/787004fdef2cabea27bad1073bf6a33f2437b4dbd3b6fb4a9d71172b1c7c/httptools-0.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b36913ba52008249223042dca46e69967985fb4051951f94357ea681e1f5dc0", size = 452042, upload-time = "2024-10-16T19:44:45.071Z" }, + { url = "https://files.pythonhosted.org/packages/4d/dc/7decab5c404d1d2cdc1bb330b1bf70e83d6af0396fd4fc76fc60c0d522bf/httptools-0.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:28908df1b9bb8187393d5b5db91435ccc9c8e891657f9cbb42a2541b44c82fc8", size = 87682, upload-time = "2024-10-16T19:44:46.46Z" }, ] [[package]] @@ -833,36 +833,36 @@ dependencies = [ { name = "httpcore" }, { name = "idna" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 } +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 }, + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, ] [[package]] name = "idna" version = "3.10" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, ] [[package]] name = "iniconfig" version = "2.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793 } +sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050 }, + { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, ] [[package]] name = "itsdangerous" version = "2.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9c/cb/8ac0172223afbccb63986cc25049b154ecfb5e85932587206f42317be31d/itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173", size = 54410 } +sdist = { url = "https://files.pythonhosted.org/packages/9c/cb/8ac0172223afbccb63986cc25049b154ecfb5e85932587206f42317be31d/itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173", size = 54410, upload-time = "2024-04-16T21:28:15.614Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", size = 16234 }, + { url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", size = 16234, upload-time = "2024-04-16T21:28:14.499Z" }, ] [[package]] @@ -872,9 +872,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115 } +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899 }, + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, ] [[package]] @@ -884,76 +884,76 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mdurl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596 } +sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 }, + { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload-time = "2023-06-03T06:41:11.019Z" }, ] [[package]] name = "markupsafe" version = "3.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/90/d08277ce111dd22f77149fd1a5d4653eeb3b3eaacbdfcbae5afb2600eebd/MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", size = 14357 }, - { url = "https://files.pythonhosted.org/packages/04/e1/6e2194baeae0bca1fae6629dc0cbbb968d4d941469cbab11a3872edff374/MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", size = 12393 }, - { url = "https://files.pythonhosted.org/packages/1d/69/35fa85a8ece0a437493dc61ce0bb6d459dcba482c34197e3efc829aa357f/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", size = 21732 }, - { url = "https://files.pythonhosted.org/packages/22/35/137da042dfb4720b638d2937c38a9c2df83fe32d20e8c8f3185dbfef05f7/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", size = 20866 }, - { url = "https://files.pythonhosted.org/packages/29/28/6d029a903727a1b62edb51863232152fd335d602def598dade38996887f0/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", size = 20964 }, - { url = "https://files.pythonhosted.org/packages/cc/cd/07438f95f83e8bc028279909d9c9bd39e24149b0d60053a97b2bc4f8aa51/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", size = 21977 }, - { url = "https://files.pythonhosted.org/packages/29/01/84b57395b4cc062f9c4c55ce0df7d3108ca32397299d9df00fedd9117d3d/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", size = 21366 }, - { url = "https://files.pythonhosted.org/packages/bd/6e/61ebf08d8940553afff20d1fb1ba7294b6f8d279df9fd0c0db911b4bbcfd/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", size = 21091 }, - { url = "https://files.pythonhosted.org/packages/11/23/ffbf53694e8c94ebd1e7e491de185124277964344733c45481f32ede2499/MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50", size = 15065 }, - { url = "https://files.pythonhosted.org/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", size = 15514 }, - { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353 }, - { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392 }, - { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984 }, - { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120 }, - { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032 }, - { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057 }, - { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359 }, - { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306 }, - { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094 }, - { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521 }, - { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274 }, - { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348 }, - { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149 }, - { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118 }, - { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993 }, - { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178 }, - { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319 }, - { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352 }, - { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097 }, - { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601 }, - { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274 }, - { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352 }, - { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122 }, - { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085 }, - { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978 }, - { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208 }, - { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357 }, - { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344 }, - { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101 }, - { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603 }, - { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510 }, - { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486 }, - { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480 }, - { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914 }, - { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796 }, - { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473 }, - { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114 }, - { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098 }, - { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208 }, - { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 }, +sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/90/d08277ce111dd22f77149fd1a5d4653eeb3b3eaacbdfcbae5afb2600eebd/MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", size = 14357, upload-time = "2024-10-18T15:20:51.44Z" }, + { url = "https://files.pythonhosted.org/packages/04/e1/6e2194baeae0bca1fae6629dc0cbbb968d4d941469cbab11a3872edff374/MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", size = 12393, upload-time = "2024-10-18T15:20:52.426Z" }, + { url = "https://files.pythonhosted.org/packages/1d/69/35fa85a8ece0a437493dc61ce0bb6d459dcba482c34197e3efc829aa357f/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", size = 21732, upload-time = "2024-10-18T15:20:53.578Z" }, + { url = "https://files.pythonhosted.org/packages/22/35/137da042dfb4720b638d2937c38a9c2df83fe32d20e8c8f3185dbfef05f7/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", size = 20866, upload-time = "2024-10-18T15:20:55.06Z" }, + { url = "https://files.pythonhosted.org/packages/29/28/6d029a903727a1b62edb51863232152fd335d602def598dade38996887f0/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", size = 20964, upload-time = "2024-10-18T15:20:55.906Z" }, + { url = "https://files.pythonhosted.org/packages/cc/cd/07438f95f83e8bc028279909d9c9bd39e24149b0d60053a97b2bc4f8aa51/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", size = 21977, upload-time = "2024-10-18T15:20:57.189Z" }, + { url = "https://files.pythonhosted.org/packages/29/01/84b57395b4cc062f9c4c55ce0df7d3108ca32397299d9df00fedd9117d3d/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", size = 21366, upload-time = "2024-10-18T15:20:58.235Z" }, + { url = "https://files.pythonhosted.org/packages/bd/6e/61ebf08d8940553afff20d1fb1ba7294b6f8d279df9fd0c0db911b4bbcfd/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", size = 21091, upload-time = "2024-10-18T15:20:59.235Z" }, + { url = "https://files.pythonhosted.org/packages/11/23/ffbf53694e8c94ebd1e7e491de185124277964344733c45481f32ede2499/MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50", size = 15065, upload-time = "2024-10-18T15:21:00.307Z" }, + { url = "https://files.pythonhosted.org/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", size = 15514, upload-time = "2024-10-18T15:21:01.122Z" }, + { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353, upload-time = "2024-10-18T15:21:02.187Z" }, + { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392, upload-time = "2024-10-18T15:21:02.941Z" }, + { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984, upload-time = "2024-10-18T15:21:03.953Z" }, + { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120, upload-time = "2024-10-18T15:21:06.495Z" }, + { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032, upload-time = "2024-10-18T15:21:07.295Z" }, + { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057, upload-time = "2024-10-18T15:21:08.073Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359, upload-time = "2024-10-18T15:21:09.318Z" }, + { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306, upload-time = "2024-10-18T15:21:10.185Z" }, + { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094, upload-time = "2024-10-18T15:21:11.005Z" }, + { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521, upload-time = "2024-10-18T15:21:12.911Z" }, + { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274, upload-time = "2024-10-18T15:21:13.777Z" }, + { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348, upload-time = "2024-10-18T15:21:14.822Z" }, + { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149, upload-time = "2024-10-18T15:21:15.642Z" }, + { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118, upload-time = "2024-10-18T15:21:17.133Z" }, + { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993, upload-time = "2024-10-18T15:21:18.064Z" }, + { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178, upload-time = "2024-10-18T15:21:18.859Z" }, + { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319, upload-time = "2024-10-18T15:21:19.671Z" }, + { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352, upload-time = "2024-10-18T15:21:20.971Z" }, + { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097, upload-time = "2024-10-18T15:21:22.646Z" }, + { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601, upload-time = "2024-10-18T15:21:23.499Z" }, + { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274, upload-time = "2024-10-18T15:21:24.577Z" }, + { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352, upload-time = "2024-10-18T15:21:25.382Z" }, + { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122, upload-time = "2024-10-18T15:21:26.199Z" }, + { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085, upload-time = "2024-10-18T15:21:27.029Z" }, + { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978, upload-time = "2024-10-18T15:21:27.846Z" }, + { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208, upload-time = "2024-10-18T15:21:28.744Z" }, + { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357, upload-time = "2024-10-18T15:21:29.545Z" }, + { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344, upload-time = "2024-10-18T15:21:30.366Z" }, + { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101, upload-time = "2024-10-18T15:21:31.207Z" }, + { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603, upload-time = "2024-10-18T15:21:32.032Z" }, + { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510, upload-time = "2024-10-18T15:21:33.625Z" }, + { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486, upload-time = "2024-10-18T15:21:34.611Z" }, + { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480, upload-time = "2024-10-18T15:21:35.398Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914, upload-time = "2024-10-18T15:21:36.231Z" }, + { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796, upload-time = "2024-10-18T15:21:37.073Z" }, + { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473, upload-time = "2024-10-18T15:21:37.932Z" }, + { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114, upload-time = "2024-10-18T15:21:39.799Z" }, + { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload-time = "2024-10-18T15:21:40.813Z" }, + { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload-time = "2024-10-18T15:21:41.814Z" }, + { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload-time = "2024-10-18T15:21:42.784Z" }, ] [[package]] name = "mdurl" version = "0.1.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, ] [[package]] @@ -963,103 +963,103 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/91/2f/a3470242707058fe856fe59241eee5635d79087100b7042a867368863a27/multidict-6.4.4.tar.gz", hash = "sha256:69ee9e6ba214b5245031b76233dd95408a0fd57fdb019ddcc1ead4790932a8e8", size = 90183 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1f/92/0926a5baafa164b5d0ade3cd7932be39310375d7e25c9d7ceca05cb26a45/multidict-6.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8adee3ac041145ffe4488ea73fa0a622b464cc25340d98be76924d0cda8545ff", size = 66052 }, - { url = "https://files.pythonhosted.org/packages/b2/54/8a857ae4f8f643ec444d91f419fdd49cc7a90a2ca0e42d86482b604b63bd/multidict-6.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b61e98c3e2a861035aaccd207da585bdcacef65fe01d7a0d07478efac005e028", size = 38867 }, - { url = "https://files.pythonhosted.org/packages/9e/5f/63add9069f945c19bc8b217ea6b0f8a1ad9382eab374bb44fae4354b3baf/multidict-6.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:75493f28dbadecdbb59130e74fe935288813301a8554dc32f0c631b6bdcdf8b0", size = 38138 }, - { url = "https://files.pythonhosted.org/packages/97/8b/fbd9c0fc13966efdb4a47f5bcffff67a4f2a3189fbeead5766eaa4250b20/multidict-6.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffc3c6a37e048b5395ee235e4a2a0d639c2349dffa32d9367a42fc20d399772", size = 220433 }, - { url = "https://files.pythonhosted.org/packages/a9/c4/5132b2d75b3ea2daedb14d10f91028f09f74f5b4d373b242c1b8eec47571/multidict-6.4.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:87cb72263946b301570b0f63855569a24ee8758aaae2cd182aae7d95fbc92ca7", size = 218059 }, - { url = "https://files.pythonhosted.org/packages/1a/70/f1e818c7a29b908e2d7b4fafb1d7939a41c64868e79de2982eea0a13193f/multidict-6.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9bbf7bd39822fd07e3609b6b4467af4c404dd2b88ee314837ad1830a7f4a8299", size = 231120 }, - { url = "https://files.pythonhosted.org/packages/b4/7e/95a194d85f27d5ef9cbe48dff9ded722fc6d12fedf641ec6e1e680890be7/multidict-6.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1f7cbd4f1f44ddf5fd86a8675b7679176eae770f2fc88115d6dddb6cefb59bc", size = 227457 }, - { url = "https://files.pythonhosted.org/packages/25/2b/590ad220968d1babb42f265debe7be5c5c616df6c5688c995a06d8a9b025/multidict-6.4.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb5ac9e5bfce0e6282e7f59ff7b7b9a74aa8e5c60d38186a4637f5aa764046ad", size = 219111 }, - { url = "https://files.pythonhosted.org/packages/e0/f0/b07682b995d3fb5313f339b59d7de02db19ba0c02d1f77c27bdf8212d17c/multidict-6.4.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4efc31dfef8c4eeb95b6b17d799eedad88c4902daba39ce637e23a17ea078915", size = 213012 }, - { url = "https://files.pythonhosted.org/packages/24/56/c77b5f36feef2ec92f1119756e468ac9c3eebc35aa8a4c9e51df664cbbc9/multidict-6.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9fcad2945b1b91c29ef2b4050f590bfcb68d8ac8e0995a74e659aa57e8d78e01", size = 225408 }, - { url = "https://files.pythonhosted.org/packages/cc/b3/e8189b82af9b198b47bc637766208fc917189eea91d674bad417e657bbdf/multidict-6.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d877447e7368c7320832acb7159557e49b21ea10ffeb135c1077dbbc0816b598", size = 214396 }, - { url = "https://files.pythonhosted.org/packages/20/e0/200d14c84e35ae13ee99fd65dc106e1a1acb87a301f15e906fc7d5b30c17/multidict-6.4.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:33a12ebac9f380714c298cbfd3e5b9c0c4e89c75fe612ae496512ee51028915f", size = 222237 }, - { url = "https://files.pythonhosted.org/packages/13/f3/bb3df40045ca8262694a3245298732ff431dc781414a89a6a364ebac6840/multidict-6.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0f14ea68d29b43a9bf37953881b1e3eb75b2739e896ba4a6aa4ad4c5b9ffa145", size = 231425 }, - { url = "https://files.pythonhosted.org/packages/85/3b/538563dc18514384dac169bcba938753ad9ab4d4c8d49b55d6ae49fb2579/multidict-6.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0327ad2c747a6600e4797d115d3c38a220fdb28e54983abe8964fd17e95ae83c", size = 226251 }, - { url = "https://files.pythonhosted.org/packages/56/79/77e1a65513f09142358f1beb1d4cbc06898590b34a7de2e47023e3c5a3a2/multidict-6.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d1a20707492db9719a05fc62ee215fd2c29b22b47c1b1ba347f9abc831e26683", size = 220363 }, - { url = "https://files.pythonhosted.org/packages/16/57/67b0516c3e348f8daaa79c369b3de4359a19918320ab82e2e586a1c624ef/multidict-6.4.4-cp310-cp310-win32.whl", hash = "sha256:d83f18315b9fca5db2452d1881ef20f79593c4aa824095b62cb280019ef7aa3d", size = 35175 }, - { url = "https://files.pythonhosted.org/packages/86/5a/4ed8fec642d113fa653777cda30ef67aa5c8a38303c091e24c521278a6c6/multidict-6.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:9c17341ee04545fd962ae07330cb5a39977294c883485c8d74634669b1f7fe04", size = 38678 }, - { url = "https://files.pythonhosted.org/packages/19/1b/4c6e638195851524a63972c5773c7737bea7e47b1ba402186a37773acee2/multidict-6.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4f5f29794ac0e73d2a06ac03fd18870adc0135a9d384f4a306a951188ed02f95", size = 65515 }, - { url = "https://files.pythonhosted.org/packages/25/d5/10e6bca9a44b8af3c7f920743e5fc0c2bcf8c11bf7a295d4cfe00b08fb46/multidict-6.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c04157266344158ebd57b7120d9b0b35812285d26d0e78193e17ef57bfe2979a", size = 38609 }, - { url = "https://files.pythonhosted.org/packages/26/b4/91fead447ccff56247edc7f0535fbf140733ae25187a33621771ee598a18/multidict-6.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bb61ffd3ab8310d93427e460f565322c44ef12769f51f77277b4abad7b6f7223", size = 37871 }, - { url = "https://files.pythonhosted.org/packages/3b/37/cbc977cae59277e99d15bbda84cc53b5e0c4929ffd91d958347200a42ad0/multidict-6.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e0ba18a9afd495f17c351d08ebbc4284e9c9f7971d715f196b79636a4d0de44", size = 226661 }, - { url = "https://files.pythonhosted.org/packages/15/cd/7e0b57fbd4dc2fc105169c4ecce5be1a63970f23bb4ec8c721b67e11953d/multidict-6.4.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9faf1b1dcaadf9f900d23a0e6d6c8eadd6a95795a0e57fcca73acce0eb912065", size = 223422 }, - { url = "https://files.pythonhosted.org/packages/f1/01/1de268da121bac9f93242e30cd3286f6a819e5f0b8896511162d6ed4bf8d/multidict-6.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a4d1cb1327c6082c4fce4e2a438483390964c02213bc6b8d782cf782c9b1471f", size = 235447 }, - { url = "https://files.pythonhosted.org/packages/d2/8c/8b9a5e4aaaf4f2de14e86181a3a3d7b105077f668b6a06f043ec794f684c/multidict-6.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:941f1bec2f5dbd51feeb40aea654c2747f811ab01bdd3422a48a4e4576b7d76a", size = 231455 }, - { url = "https://files.pythonhosted.org/packages/35/db/e1817dcbaa10b319c412769cf999b1016890849245d38905b73e9c286862/multidict-6.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5f8a146184da7ea12910a4cec51ef85e44f6268467fb489c3caf0cd512f29c2", size = 223666 }, - { url = "https://files.pythonhosted.org/packages/4a/e1/66e8579290ade8a00e0126b3d9a93029033ffd84f0e697d457ed1814d0fc/multidict-6.4.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:232b7237e57ec3c09be97206bfb83a0aa1c5d7d377faa019c68a210fa35831f1", size = 217392 }, - { url = "https://files.pythonhosted.org/packages/7b/6f/f8639326069c24a48c7747c2a5485d37847e142a3f741ff3340c88060a9a/multidict-6.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:55ae0721c1513e5e3210bca4fc98456b980b0c2c016679d3d723119b6b202c42", size = 228969 }, - { url = "https://files.pythonhosted.org/packages/d2/c3/3d58182f76b960eeade51c89fcdce450f93379340457a328e132e2f8f9ed/multidict-6.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:51d662c072579f63137919d7bb8fc250655ce79f00c82ecf11cab678f335062e", size = 217433 }, - { url = "https://files.pythonhosted.org/packages/e1/4b/f31a562906f3bd375f3d0e83ce314e4a660c01b16c2923e8229b53fba5d7/multidict-6.4.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0e05c39962baa0bb19a6b210e9b1422c35c093b651d64246b6c2e1a7e242d9fd", size = 225418 }, - { url = "https://files.pythonhosted.org/packages/99/89/78bb95c89c496d64b5798434a3deee21996114d4d2c28dd65850bf3a691e/multidict-6.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d5b1cc3ab8c31d9ebf0faa6e3540fb91257590da330ffe6d2393d4208e638925", size = 235042 }, - { url = "https://files.pythonhosted.org/packages/74/91/8780a6e5885a8770442a8f80db86a0887c4becca0e5a2282ba2cae702bc4/multidict-6.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:93ec84488a384cd7b8a29c2c7f467137d8a73f6fe38bb810ecf29d1ade011a7c", size = 230280 }, - { url = "https://files.pythonhosted.org/packages/68/c1/fcf69cabd542eb6f4b892469e033567ee6991d361d77abdc55e3a0f48349/multidict-6.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b308402608493638763abc95f9dc0030bbd6ac6aff784512e8ac3da73a88af08", size = 223322 }, - { url = "https://files.pythonhosted.org/packages/b8/85/5b80bf4b83d8141bd763e1d99142a9cdfd0db83f0739b4797172a4508014/multidict-6.4.4-cp311-cp311-win32.whl", hash = "sha256:343892a27d1a04d6ae455ecece12904d242d299ada01633d94c4f431d68a8c49", size = 35070 }, - { url = "https://files.pythonhosted.org/packages/09/66/0bed198ffd590ab86e001f7fa46b740d58cf8ff98c2f254e4a36bf8861ad/multidict-6.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:73484a94f55359780c0f458bbd3c39cb9cf9c182552177d2136e828269dee529", size = 38667 }, - { url = "https://files.pythonhosted.org/packages/d2/b5/5675377da23d60875fe7dae6be841787755878e315e2f517235f22f59e18/multidict-6.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:dc388f75a1c00000824bf28b7633e40854f4127ede80512b44c3cfeeea1839a2", size = 64293 }, - { url = "https://files.pythonhosted.org/packages/34/a7/be384a482754bb8c95d2bbe91717bf7ccce6dc38c18569997a11f95aa554/multidict-6.4.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:98af87593a666f739d9dba5d0ae86e01b0e1a9cfcd2e30d2d361fbbbd1a9162d", size = 38096 }, - { url = "https://files.pythonhosted.org/packages/66/6d/d59854bb4352306145bdfd1704d210731c1bb2c890bfee31fb7bbc1c4c7f/multidict-6.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aff4cafea2d120327d55eadd6b7f1136a8e5a0ecf6fb3b6863e8aca32cd8e50a", size = 37214 }, - { url = "https://files.pythonhosted.org/packages/99/e0/c29d9d462d7cfc5fc8f9bf24f9c6843b40e953c0b55e04eba2ad2cf54fba/multidict-6.4.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:169c4ba7858176b797fe551d6e99040c531c775d2d57b31bcf4de6d7a669847f", size = 224686 }, - { url = "https://files.pythonhosted.org/packages/dc/4a/da99398d7fd8210d9de068f9a1b5f96dfaf67d51e3f2521f17cba4ee1012/multidict-6.4.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b9eb4c59c54421a32b3273d4239865cb14ead53a606db066d7130ac80cc8ec93", size = 231061 }, - { url = "https://files.pythonhosted.org/packages/21/f5/ac11add39a0f447ac89353e6ca46666847051103649831c08a2800a14455/multidict-6.4.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7cf3bd54c56aa16fdb40028d545eaa8d051402b61533c21e84046e05513d5780", size = 232412 }, - { url = "https://files.pythonhosted.org/packages/d9/11/4b551e2110cded705a3c13a1d4b6a11f73891eb5a1c449f1b2b6259e58a6/multidict-6.4.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f682c42003c7264134bfe886376299db4cc0c6cd06a3295b41b347044bcb5482", size = 231563 }, - { url = "https://files.pythonhosted.org/packages/4c/02/751530c19e78fe73b24c3da66618eda0aa0d7f6e7aa512e46483de6be210/multidict-6.4.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920f9cf2abdf6e493c519492d892c362007f113c94da4c239ae88429835bad1", size = 223811 }, - { url = "https://files.pythonhosted.org/packages/c7/cb/2be8a214643056289e51ca356026c7b2ce7225373e7a1f8c8715efee8988/multidict-6.4.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:530d86827a2df6504526106b4c104ba19044594f8722d3e87714e847c74a0275", size = 216524 }, - { url = "https://files.pythonhosted.org/packages/19/f3/6d5011ec375c09081f5250af58de85f172bfcaafebff286d8089243c4bd4/multidict-6.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ecde56ea2439b96ed8a8d826b50c57364612ddac0438c39e473fafad7ae1c23b", size = 229012 }, - { url = "https://files.pythonhosted.org/packages/67/9c/ca510785df5cf0eaf5b2a8132d7d04c1ce058dcf2c16233e596ce37a7f8e/multidict-6.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:dc8c9736d8574b560634775ac0def6bdc1661fc63fa27ffdfc7264c565bcb4f2", size = 226765 }, - { url = "https://files.pythonhosted.org/packages/36/c8/ca86019994e92a0f11e642bda31265854e6ea7b235642f0477e8c2e25c1f/multidict-6.4.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7f3d3b3c34867579ea47cbd6c1f2ce23fbfd20a273b6f9e3177e256584f1eacc", size = 222888 }, - { url = "https://files.pythonhosted.org/packages/c6/67/bc25a8e8bd522935379066950ec4e2277f9b236162a73548a2576d4b9587/multidict-6.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:87a728af265e08f96b6318ebe3c0f68b9335131f461efab2fc64cc84a44aa6ed", size = 234041 }, - { url = "https://files.pythonhosted.org/packages/f1/a0/70c4c2d12857fccbe607b334b7ee28b6b5326c322ca8f73ee54e70d76484/multidict-6.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9f193eeda1857f8e8d3079a4abd258f42ef4a4bc87388452ed1e1c4d2b0c8740", size = 231046 }, - { url = "https://files.pythonhosted.org/packages/c1/0f/52954601d02d39742aab01d6b92f53c1dd38b2392248154c50797b4df7f1/multidict-6.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be06e73c06415199200e9a2324a11252a3d62030319919cde5e6950ffeccf72e", size = 227106 }, - { url = "https://files.pythonhosted.org/packages/af/24/679d83ec4379402d28721790dce818e5d6b9f94ce1323a556fb17fa9996c/multidict-6.4.4-cp312-cp312-win32.whl", hash = "sha256:622f26ea6a7e19b7c48dd9228071f571b2fbbd57a8cd71c061e848f281550e6b", size = 35351 }, - { url = "https://files.pythonhosted.org/packages/52/ef/40d98bc5f986f61565f9b345f102409534e29da86a6454eb6b7c00225a13/multidict-6.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:5e2bcda30d5009996ff439e02a9f2b5c3d64a20151d34898c000a6281faa3781", size = 38791 }, - { url = "https://files.pythonhosted.org/packages/df/2a/e166d2ffbf4b10131b2d5b0e458f7cee7d986661caceae0de8753042d4b2/multidict-6.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:82ffabefc8d84c2742ad19c37f02cde5ec2a1ee172d19944d380f920a340e4b9", size = 64123 }, - { url = "https://files.pythonhosted.org/packages/8c/96/e200e379ae5b6f95cbae472e0199ea98913f03d8c9a709f42612a432932c/multidict-6.4.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6a2f58a66fe2c22615ad26156354005391e26a2f3721c3621504cd87c1ea87bf", size = 38049 }, - { url = "https://files.pythonhosted.org/packages/75/fb/47afd17b83f6a8c7fa863c6d23ac5ba6a0e6145ed8a6bcc8da20b2b2c1d2/multidict-6.4.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5883d6ee0fd9d8a48e9174df47540b7545909841ac82354c7ae4cbe9952603bd", size = 37078 }, - { url = "https://files.pythonhosted.org/packages/fa/70/1af3143000eddfb19fd5ca5e78393985ed988ac493bb859800fe0914041f/multidict-6.4.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9abcf56a9511653fa1d052bfc55fbe53dbee8f34e68bd6a5a038731b0ca42d15", size = 224097 }, - { url = "https://files.pythonhosted.org/packages/b1/39/d570c62b53d4fba844e0378ffbcd02ac25ca423d3235047013ba2f6f60f8/multidict-6.4.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6ed5ae5605d4ad5a049fad2a28bb7193400700ce2f4ae484ab702d1e3749c3f9", size = 230768 }, - { url = "https://files.pythonhosted.org/packages/fd/f8/ed88f2c4d06f752b015933055eb291d9bc184936903752c66f68fb3c95a7/multidict-6.4.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbfcb60396f9bcfa63e017a180c3105b8c123a63e9d1428a36544e7d37ca9e20", size = 231331 }, - { url = "https://files.pythonhosted.org/packages/9c/6f/8e07cffa32f483ab887b0d56bbd8747ac2c1acd00dc0af6fcf265f4a121e/multidict-6.4.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0f1987787f5f1e2076b59692352ab29a955b09ccc433c1f6b8e8e18666f608b", size = 230169 }, - { url = "https://files.pythonhosted.org/packages/e6/2b/5dcf173be15e42f330110875a2668ddfc208afc4229097312212dc9c1236/multidict-6.4.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d0121ccce8c812047d8d43d691a1ad7641f72c4f730474878a5aeae1b8ead8c", size = 222947 }, - { url = "https://files.pythonhosted.org/packages/39/75/4ddcbcebe5ebcd6faa770b629260d15840a5fc07ce8ad295a32e14993726/multidict-6.4.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ec4967114295b8afd120a8eec579920c882831a3e4c3331d591a8e5bfbbc0f", size = 215761 }, - { url = "https://files.pythonhosted.org/packages/6a/c9/55e998ae45ff15c5608e384206aa71a11e1b7f48b64d166db400b14a3433/multidict-6.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:995f985e2e268deaf17867801b859a282e0448633f1310e3704b30616d269d69", size = 227605 }, - { url = "https://files.pythonhosted.org/packages/04/49/c2404eac74497503c77071bd2e6f88c7e94092b8a07601536b8dbe99be50/multidict-6.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:d832c608f94b9f92a0ec8b7e949be7792a642b6e535fcf32f3e28fab69eeb046", size = 226144 }, - { url = "https://files.pythonhosted.org/packages/62/c5/0cd0c3c6f18864c40846aa2252cd69d308699cb163e1c0d989ca301684da/multidict-6.4.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d21c1212171cf7da703c5b0b7a0e85be23b720818aef502ad187d627316d5645", size = 221100 }, - { url = "https://files.pythonhosted.org/packages/71/7b/f2f3887bea71739a046d601ef10e689528d4f911d84da873b6be9194ffea/multidict-6.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:cbebaa076aaecad3d4bb4c008ecc73b09274c952cf6a1b78ccfd689e51f5a5b0", size = 232731 }, - { url = "https://files.pythonhosted.org/packages/e5/b3/d9de808349df97fa75ec1372758701b5800ebad3c46ae377ad63058fbcc6/multidict-6.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:c93a6fb06cc8e5d3628b2b5fda215a5db01e8f08fc15fadd65662d9b857acbe4", size = 229637 }, - { url = "https://files.pythonhosted.org/packages/5e/57/13207c16b615eb4f1745b44806a96026ef8e1b694008a58226c2d8f5f0a5/multidict-6.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8cd8f81f1310182362fb0c7898145ea9c9b08a71081c5963b40ee3e3cac589b1", size = 225594 }, - { url = "https://files.pythonhosted.org/packages/3a/e4/d23bec2f70221604f5565000632c305fc8f25ba953e8ce2d8a18842b9841/multidict-6.4.4-cp313-cp313-win32.whl", hash = "sha256:3e9f1cd61a0ab857154205fb0b1f3d3ace88d27ebd1409ab7af5096e409614cd", size = 35359 }, - { url = "https://files.pythonhosted.org/packages/a7/7a/cfe1a47632be861b627f46f642c1d031704cc1c0f5c0efbde2ad44aa34bd/multidict-6.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:8ffb40b74400e4455785c2fa37eba434269149ec525fc8329858c862e4b35373", size = 38903 }, - { url = "https://files.pythonhosted.org/packages/68/7b/15c259b0ab49938a0a1c8f3188572802704a779ddb294edc1b2a72252e7c/multidict-6.4.4-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:6a602151dbf177be2450ef38966f4be3467d41a86c6a845070d12e17c858a156", size = 68895 }, - { url = "https://files.pythonhosted.org/packages/f1/7d/168b5b822bccd88142e0a3ce985858fea612404edd228698f5af691020c9/multidict-6.4.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0d2b9712211b860d123815a80b859075d86a4d54787e247d7fbee9db6832cf1c", size = 40183 }, - { url = "https://files.pythonhosted.org/packages/e0/b7/d4b8d98eb850ef28a4922ba508c31d90715fd9b9da3801a30cea2967130b/multidict-6.4.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d2fa86af59f8fc1972e121ade052145f6da22758f6996a197d69bb52f8204e7e", size = 39592 }, - { url = "https://files.pythonhosted.org/packages/18/28/a554678898a19583548e742080cf55d169733baf57efc48c2f0273a08583/multidict-6.4.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50855d03e9e4d66eab6947ba688ffb714616f985838077bc4b490e769e48da51", size = 226071 }, - { url = "https://files.pythonhosted.org/packages/ee/dc/7ba6c789d05c310e294f85329efac1bf5b450338d2542498db1491a264df/multidict-6.4.4-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5bce06b83be23225be1905dcdb6b789064fae92499fbc458f59a8c0e68718601", size = 222597 }, - { url = "https://files.pythonhosted.org/packages/24/4f/34eadbbf401b03768dba439be0fb94b0d187facae9142821a3d5599ccb3b/multidict-6.4.4-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66ed0731f8e5dfd8369a883b6e564aca085fb9289aacabd9decd70568b9a30de", size = 228253 }, - { url = "https://files.pythonhosted.org/packages/c0/e6/493225a3cdb0d8d80d43a94503fc313536a07dae54a3f030d279e629a2bc/multidict-6.4.4-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:329ae97fc2f56f44d91bc47fe0972b1f52d21c4b7a2ac97040da02577e2daca2", size = 226146 }, - { url = "https://files.pythonhosted.org/packages/2f/70/e411a7254dc3bff6f7e6e004303b1b0591358e9f0b7c08639941e0de8bd6/multidict-6.4.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c27e5dcf520923d6474d98b96749e6805f7677e93aaaf62656005b8643f907ab", size = 220585 }, - { url = "https://files.pythonhosted.org/packages/08/8f/beb3ae7406a619100d2b1fb0022c3bb55a8225ab53c5663648ba50dfcd56/multidict-6.4.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:058cc59b9e9b143cc56715e59e22941a5d868c322242278d28123a5d09cdf6b0", size = 212080 }, - { url = "https://files.pythonhosted.org/packages/9c/ec/355124e9d3d01cf8edb072fd14947220f357e1c5bc79c88dff89297e9342/multidict-6.4.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:69133376bc9a03f8c47343d33f91f74a99c339e8b58cea90433d8e24bb298031", size = 226558 }, - { url = "https://files.pythonhosted.org/packages/fd/22/d2b95cbebbc2ada3be3812ea9287dcc9712d7f1a012fad041770afddb2ad/multidict-6.4.4-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:d6b15c55721b1b115c5ba178c77104123745b1417527ad9641a4c5e2047450f0", size = 212168 }, - { url = "https://files.pythonhosted.org/packages/4d/c5/62bfc0b2f9ce88326dbe7179f9824a939c6c7775b23b95de777267b9725c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:a887b77f51d3d41e6e1a63cf3bc7ddf24de5939d9ff69441387dfefa58ac2e26", size = 217970 }, - { url = "https://files.pythonhosted.org/packages/79/74/977cea1aadc43ff1c75d23bd5bc4768a8fac98c14e5878d6ee8d6bab743c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:632a3bf8f1787f7ef7d3c2f68a7bde5be2f702906f8b5842ad6da9d974d0aab3", size = 226980 }, - { url = "https://files.pythonhosted.org/packages/48/fc/cc4a1a2049df2eb84006607dc428ff237af38e0fcecfdb8a29ca47b1566c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:a145c550900deb7540973c5cdb183b0d24bed6b80bf7bddf33ed8f569082535e", size = 220641 }, - { url = "https://files.pythonhosted.org/packages/3b/6a/a7444d113ab918701988d4abdde373dbdfd2def7bd647207e2bf645c7eac/multidict-6.4.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc5d83c6619ca5c9672cb78b39ed8542f1975a803dee2cda114ff73cbb076edd", size = 221728 }, - { url = "https://files.pythonhosted.org/packages/2b/b0/fdf4c73ad1c55e0f4dbbf2aa59dd37037334091f9a4961646d2b7ac91a86/multidict-6.4.4-cp313-cp313t-win32.whl", hash = "sha256:3312f63261b9df49be9d57aaa6abf53a6ad96d93b24f9cc16cf979956355ce6e", size = 41913 }, - { url = "https://files.pythonhosted.org/packages/8e/92/27989ecca97e542c0d01d05a98a5ae12198a243a9ee12563a0313291511f/multidict-6.4.4-cp313-cp313t-win_amd64.whl", hash = "sha256:ba852168d814b2c73333073e1c7116d9395bea69575a01b0b3c89d2d5a87c8fb", size = 46112 }, - { url = "https://files.pythonhosted.org/packages/84/5d/e17845bb0fa76334477d5de38654d27946d5b5d3695443987a094a71b440/multidict-6.4.4-py3-none-any.whl", hash = "sha256:bd4557071b561a8b3b6075c3ce93cf9bfb6182cb241805c3d66ced3b75eff4ac", size = 10481 }, +sdist = { url = "https://files.pythonhosted.org/packages/91/2f/a3470242707058fe856fe59241eee5635d79087100b7042a867368863a27/multidict-6.4.4.tar.gz", hash = "sha256:69ee9e6ba214b5245031b76233dd95408a0fd57fdb019ddcc1ead4790932a8e8", size = 90183, upload-time = "2025-05-19T14:16:37.381Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1f/92/0926a5baafa164b5d0ade3cd7932be39310375d7e25c9d7ceca05cb26a45/multidict-6.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8adee3ac041145ffe4488ea73fa0a622b464cc25340d98be76924d0cda8545ff", size = 66052, upload-time = "2025-05-19T14:13:49.944Z" }, + { url = "https://files.pythonhosted.org/packages/b2/54/8a857ae4f8f643ec444d91f419fdd49cc7a90a2ca0e42d86482b604b63bd/multidict-6.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b61e98c3e2a861035aaccd207da585bdcacef65fe01d7a0d07478efac005e028", size = 38867, upload-time = "2025-05-19T14:13:51.92Z" }, + { url = "https://files.pythonhosted.org/packages/9e/5f/63add9069f945c19bc8b217ea6b0f8a1ad9382eab374bb44fae4354b3baf/multidict-6.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:75493f28dbadecdbb59130e74fe935288813301a8554dc32f0c631b6bdcdf8b0", size = 38138, upload-time = "2025-05-19T14:13:53.778Z" }, + { url = "https://files.pythonhosted.org/packages/97/8b/fbd9c0fc13966efdb4a47f5bcffff67a4f2a3189fbeead5766eaa4250b20/multidict-6.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffc3c6a37e048b5395ee235e4a2a0d639c2349dffa32d9367a42fc20d399772", size = 220433, upload-time = "2025-05-19T14:13:55.346Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c4/5132b2d75b3ea2daedb14d10f91028f09f74f5b4d373b242c1b8eec47571/multidict-6.4.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:87cb72263946b301570b0f63855569a24ee8758aaae2cd182aae7d95fbc92ca7", size = 218059, upload-time = "2025-05-19T14:13:56.993Z" }, + { url = "https://files.pythonhosted.org/packages/1a/70/f1e818c7a29b908e2d7b4fafb1d7939a41c64868e79de2982eea0a13193f/multidict-6.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9bbf7bd39822fd07e3609b6b4467af4c404dd2b88ee314837ad1830a7f4a8299", size = 231120, upload-time = "2025-05-19T14:13:58.333Z" }, + { url = "https://files.pythonhosted.org/packages/b4/7e/95a194d85f27d5ef9cbe48dff9ded722fc6d12fedf641ec6e1e680890be7/multidict-6.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1f7cbd4f1f44ddf5fd86a8675b7679176eae770f2fc88115d6dddb6cefb59bc", size = 227457, upload-time = "2025-05-19T14:13:59.663Z" }, + { url = "https://files.pythonhosted.org/packages/25/2b/590ad220968d1babb42f265debe7be5c5c616df6c5688c995a06d8a9b025/multidict-6.4.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb5ac9e5bfce0e6282e7f59ff7b7b9a74aa8e5c60d38186a4637f5aa764046ad", size = 219111, upload-time = "2025-05-19T14:14:01.019Z" }, + { url = "https://files.pythonhosted.org/packages/e0/f0/b07682b995d3fb5313f339b59d7de02db19ba0c02d1f77c27bdf8212d17c/multidict-6.4.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4efc31dfef8c4eeb95b6b17d799eedad88c4902daba39ce637e23a17ea078915", size = 213012, upload-time = "2025-05-19T14:14:02.396Z" }, + { url = "https://files.pythonhosted.org/packages/24/56/c77b5f36feef2ec92f1119756e468ac9c3eebc35aa8a4c9e51df664cbbc9/multidict-6.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9fcad2945b1b91c29ef2b4050f590bfcb68d8ac8e0995a74e659aa57e8d78e01", size = 225408, upload-time = "2025-05-19T14:14:04.826Z" }, + { url = "https://files.pythonhosted.org/packages/cc/b3/e8189b82af9b198b47bc637766208fc917189eea91d674bad417e657bbdf/multidict-6.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d877447e7368c7320832acb7159557e49b21ea10ffeb135c1077dbbc0816b598", size = 214396, upload-time = "2025-05-19T14:14:06.187Z" }, + { url = "https://files.pythonhosted.org/packages/20/e0/200d14c84e35ae13ee99fd65dc106e1a1acb87a301f15e906fc7d5b30c17/multidict-6.4.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:33a12ebac9f380714c298cbfd3e5b9c0c4e89c75fe612ae496512ee51028915f", size = 222237, upload-time = "2025-05-19T14:14:07.778Z" }, + { url = "https://files.pythonhosted.org/packages/13/f3/bb3df40045ca8262694a3245298732ff431dc781414a89a6a364ebac6840/multidict-6.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0f14ea68d29b43a9bf37953881b1e3eb75b2739e896ba4a6aa4ad4c5b9ffa145", size = 231425, upload-time = "2025-05-19T14:14:09.516Z" }, + { url = "https://files.pythonhosted.org/packages/85/3b/538563dc18514384dac169bcba938753ad9ab4d4c8d49b55d6ae49fb2579/multidict-6.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0327ad2c747a6600e4797d115d3c38a220fdb28e54983abe8964fd17e95ae83c", size = 226251, upload-time = "2025-05-19T14:14:10.82Z" }, + { url = "https://files.pythonhosted.org/packages/56/79/77e1a65513f09142358f1beb1d4cbc06898590b34a7de2e47023e3c5a3a2/multidict-6.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d1a20707492db9719a05fc62ee215fd2c29b22b47c1b1ba347f9abc831e26683", size = 220363, upload-time = "2025-05-19T14:14:12.638Z" }, + { url = "https://files.pythonhosted.org/packages/16/57/67b0516c3e348f8daaa79c369b3de4359a19918320ab82e2e586a1c624ef/multidict-6.4.4-cp310-cp310-win32.whl", hash = "sha256:d83f18315b9fca5db2452d1881ef20f79593c4aa824095b62cb280019ef7aa3d", size = 35175, upload-time = "2025-05-19T14:14:14.805Z" }, + { url = "https://files.pythonhosted.org/packages/86/5a/4ed8fec642d113fa653777cda30ef67aa5c8a38303c091e24c521278a6c6/multidict-6.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:9c17341ee04545fd962ae07330cb5a39977294c883485c8d74634669b1f7fe04", size = 38678, upload-time = "2025-05-19T14:14:16.949Z" }, + { url = "https://files.pythonhosted.org/packages/19/1b/4c6e638195851524a63972c5773c7737bea7e47b1ba402186a37773acee2/multidict-6.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4f5f29794ac0e73d2a06ac03fd18870adc0135a9d384f4a306a951188ed02f95", size = 65515, upload-time = "2025-05-19T14:14:19.767Z" }, + { url = "https://files.pythonhosted.org/packages/25/d5/10e6bca9a44b8af3c7f920743e5fc0c2bcf8c11bf7a295d4cfe00b08fb46/multidict-6.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c04157266344158ebd57b7120d9b0b35812285d26d0e78193e17ef57bfe2979a", size = 38609, upload-time = "2025-05-19T14:14:21.538Z" }, + { url = "https://files.pythonhosted.org/packages/26/b4/91fead447ccff56247edc7f0535fbf140733ae25187a33621771ee598a18/multidict-6.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bb61ffd3ab8310d93427e460f565322c44ef12769f51f77277b4abad7b6f7223", size = 37871, upload-time = "2025-05-19T14:14:22.666Z" }, + { url = "https://files.pythonhosted.org/packages/3b/37/cbc977cae59277e99d15bbda84cc53b5e0c4929ffd91d958347200a42ad0/multidict-6.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e0ba18a9afd495f17c351d08ebbc4284e9c9f7971d715f196b79636a4d0de44", size = 226661, upload-time = "2025-05-19T14:14:24.124Z" }, + { url = "https://files.pythonhosted.org/packages/15/cd/7e0b57fbd4dc2fc105169c4ecce5be1a63970f23bb4ec8c721b67e11953d/multidict-6.4.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9faf1b1dcaadf9f900d23a0e6d6c8eadd6a95795a0e57fcca73acce0eb912065", size = 223422, upload-time = "2025-05-19T14:14:25.437Z" }, + { url = "https://files.pythonhosted.org/packages/f1/01/1de268da121bac9f93242e30cd3286f6a819e5f0b8896511162d6ed4bf8d/multidict-6.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a4d1cb1327c6082c4fce4e2a438483390964c02213bc6b8d782cf782c9b1471f", size = 235447, upload-time = "2025-05-19T14:14:26.793Z" }, + { url = "https://files.pythonhosted.org/packages/d2/8c/8b9a5e4aaaf4f2de14e86181a3a3d7b105077f668b6a06f043ec794f684c/multidict-6.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:941f1bec2f5dbd51feeb40aea654c2747f811ab01bdd3422a48a4e4576b7d76a", size = 231455, upload-time = "2025-05-19T14:14:28.149Z" }, + { url = "https://files.pythonhosted.org/packages/35/db/e1817dcbaa10b319c412769cf999b1016890849245d38905b73e9c286862/multidict-6.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5f8a146184da7ea12910a4cec51ef85e44f6268467fb489c3caf0cd512f29c2", size = 223666, upload-time = "2025-05-19T14:14:29.584Z" }, + { url = "https://files.pythonhosted.org/packages/4a/e1/66e8579290ade8a00e0126b3d9a93029033ffd84f0e697d457ed1814d0fc/multidict-6.4.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:232b7237e57ec3c09be97206bfb83a0aa1c5d7d377faa019c68a210fa35831f1", size = 217392, upload-time = "2025-05-19T14:14:30.961Z" }, + { url = "https://files.pythonhosted.org/packages/7b/6f/f8639326069c24a48c7747c2a5485d37847e142a3f741ff3340c88060a9a/multidict-6.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:55ae0721c1513e5e3210bca4fc98456b980b0c2c016679d3d723119b6b202c42", size = 228969, upload-time = "2025-05-19T14:14:32.672Z" }, + { url = "https://files.pythonhosted.org/packages/d2/c3/3d58182f76b960eeade51c89fcdce450f93379340457a328e132e2f8f9ed/multidict-6.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:51d662c072579f63137919d7bb8fc250655ce79f00c82ecf11cab678f335062e", size = 217433, upload-time = "2025-05-19T14:14:34.016Z" }, + { url = "https://files.pythonhosted.org/packages/e1/4b/f31a562906f3bd375f3d0e83ce314e4a660c01b16c2923e8229b53fba5d7/multidict-6.4.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0e05c39962baa0bb19a6b210e9b1422c35c093b651d64246b6c2e1a7e242d9fd", size = 225418, upload-time = "2025-05-19T14:14:35.376Z" }, + { url = "https://files.pythonhosted.org/packages/99/89/78bb95c89c496d64b5798434a3deee21996114d4d2c28dd65850bf3a691e/multidict-6.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d5b1cc3ab8c31d9ebf0faa6e3540fb91257590da330ffe6d2393d4208e638925", size = 235042, upload-time = "2025-05-19T14:14:36.723Z" }, + { url = "https://files.pythonhosted.org/packages/74/91/8780a6e5885a8770442a8f80db86a0887c4becca0e5a2282ba2cae702bc4/multidict-6.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:93ec84488a384cd7b8a29c2c7f467137d8a73f6fe38bb810ecf29d1ade011a7c", size = 230280, upload-time = "2025-05-19T14:14:38.194Z" }, + { url = "https://files.pythonhosted.org/packages/68/c1/fcf69cabd542eb6f4b892469e033567ee6991d361d77abdc55e3a0f48349/multidict-6.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b308402608493638763abc95f9dc0030bbd6ac6aff784512e8ac3da73a88af08", size = 223322, upload-time = "2025-05-19T14:14:40.015Z" }, + { url = "https://files.pythonhosted.org/packages/b8/85/5b80bf4b83d8141bd763e1d99142a9cdfd0db83f0739b4797172a4508014/multidict-6.4.4-cp311-cp311-win32.whl", hash = "sha256:343892a27d1a04d6ae455ecece12904d242d299ada01633d94c4f431d68a8c49", size = 35070, upload-time = "2025-05-19T14:14:41.904Z" }, + { url = "https://files.pythonhosted.org/packages/09/66/0bed198ffd590ab86e001f7fa46b740d58cf8ff98c2f254e4a36bf8861ad/multidict-6.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:73484a94f55359780c0f458bbd3c39cb9cf9c182552177d2136e828269dee529", size = 38667, upload-time = "2025-05-19T14:14:43.534Z" }, + { url = "https://files.pythonhosted.org/packages/d2/b5/5675377da23d60875fe7dae6be841787755878e315e2f517235f22f59e18/multidict-6.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:dc388f75a1c00000824bf28b7633e40854f4127ede80512b44c3cfeeea1839a2", size = 64293, upload-time = "2025-05-19T14:14:44.724Z" }, + { url = "https://files.pythonhosted.org/packages/34/a7/be384a482754bb8c95d2bbe91717bf7ccce6dc38c18569997a11f95aa554/multidict-6.4.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:98af87593a666f739d9dba5d0ae86e01b0e1a9cfcd2e30d2d361fbbbd1a9162d", size = 38096, upload-time = "2025-05-19T14:14:45.95Z" }, + { url = "https://files.pythonhosted.org/packages/66/6d/d59854bb4352306145bdfd1704d210731c1bb2c890bfee31fb7bbc1c4c7f/multidict-6.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aff4cafea2d120327d55eadd6b7f1136a8e5a0ecf6fb3b6863e8aca32cd8e50a", size = 37214, upload-time = "2025-05-19T14:14:47.158Z" }, + { url = "https://files.pythonhosted.org/packages/99/e0/c29d9d462d7cfc5fc8f9bf24f9c6843b40e953c0b55e04eba2ad2cf54fba/multidict-6.4.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:169c4ba7858176b797fe551d6e99040c531c775d2d57b31bcf4de6d7a669847f", size = 224686, upload-time = "2025-05-19T14:14:48.366Z" }, + { url = "https://files.pythonhosted.org/packages/dc/4a/da99398d7fd8210d9de068f9a1b5f96dfaf67d51e3f2521f17cba4ee1012/multidict-6.4.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b9eb4c59c54421a32b3273d4239865cb14ead53a606db066d7130ac80cc8ec93", size = 231061, upload-time = "2025-05-19T14:14:49.952Z" }, + { url = "https://files.pythonhosted.org/packages/21/f5/ac11add39a0f447ac89353e6ca46666847051103649831c08a2800a14455/multidict-6.4.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7cf3bd54c56aa16fdb40028d545eaa8d051402b61533c21e84046e05513d5780", size = 232412, upload-time = "2025-05-19T14:14:51.812Z" }, + { url = "https://files.pythonhosted.org/packages/d9/11/4b551e2110cded705a3c13a1d4b6a11f73891eb5a1c449f1b2b6259e58a6/multidict-6.4.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f682c42003c7264134bfe886376299db4cc0c6cd06a3295b41b347044bcb5482", size = 231563, upload-time = "2025-05-19T14:14:53.262Z" }, + { url = "https://files.pythonhosted.org/packages/4c/02/751530c19e78fe73b24c3da66618eda0aa0d7f6e7aa512e46483de6be210/multidict-6.4.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920f9cf2abdf6e493c519492d892c362007f113c94da4c239ae88429835bad1", size = 223811, upload-time = "2025-05-19T14:14:55.232Z" }, + { url = "https://files.pythonhosted.org/packages/c7/cb/2be8a214643056289e51ca356026c7b2ce7225373e7a1f8c8715efee8988/multidict-6.4.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:530d86827a2df6504526106b4c104ba19044594f8722d3e87714e847c74a0275", size = 216524, upload-time = "2025-05-19T14:14:57.226Z" }, + { url = "https://files.pythonhosted.org/packages/19/f3/6d5011ec375c09081f5250af58de85f172bfcaafebff286d8089243c4bd4/multidict-6.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ecde56ea2439b96ed8a8d826b50c57364612ddac0438c39e473fafad7ae1c23b", size = 229012, upload-time = "2025-05-19T14:14:58.597Z" }, + { url = "https://files.pythonhosted.org/packages/67/9c/ca510785df5cf0eaf5b2a8132d7d04c1ce058dcf2c16233e596ce37a7f8e/multidict-6.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:dc8c9736d8574b560634775ac0def6bdc1661fc63fa27ffdfc7264c565bcb4f2", size = 226765, upload-time = "2025-05-19T14:15:00.048Z" }, + { url = "https://files.pythonhosted.org/packages/36/c8/ca86019994e92a0f11e642bda31265854e6ea7b235642f0477e8c2e25c1f/multidict-6.4.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7f3d3b3c34867579ea47cbd6c1f2ce23fbfd20a273b6f9e3177e256584f1eacc", size = 222888, upload-time = "2025-05-19T14:15:01.568Z" }, + { url = "https://files.pythonhosted.org/packages/c6/67/bc25a8e8bd522935379066950ec4e2277f9b236162a73548a2576d4b9587/multidict-6.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:87a728af265e08f96b6318ebe3c0f68b9335131f461efab2fc64cc84a44aa6ed", size = 234041, upload-time = "2025-05-19T14:15:03.759Z" }, + { url = "https://files.pythonhosted.org/packages/f1/a0/70c4c2d12857fccbe607b334b7ee28b6b5326c322ca8f73ee54e70d76484/multidict-6.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9f193eeda1857f8e8d3079a4abd258f42ef4a4bc87388452ed1e1c4d2b0c8740", size = 231046, upload-time = "2025-05-19T14:15:05.698Z" }, + { url = "https://files.pythonhosted.org/packages/c1/0f/52954601d02d39742aab01d6b92f53c1dd38b2392248154c50797b4df7f1/multidict-6.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be06e73c06415199200e9a2324a11252a3d62030319919cde5e6950ffeccf72e", size = 227106, upload-time = "2025-05-19T14:15:07.124Z" }, + { url = "https://files.pythonhosted.org/packages/af/24/679d83ec4379402d28721790dce818e5d6b9f94ce1323a556fb17fa9996c/multidict-6.4.4-cp312-cp312-win32.whl", hash = "sha256:622f26ea6a7e19b7c48dd9228071f571b2fbbd57a8cd71c061e848f281550e6b", size = 35351, upload-time = "2025-05-19T14:15:08.556Z" }, + { url = "https://files.pythonhosted.org/packages/52/ef/40d98bc5f986f61565f9b345f102409534e29da86a6454eb6b7c00225a13/multidict-6.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:5e2bcda30d5009996ff439e02a9f2b5c3d64a20151d34898c000a6281faa3781", size = 38791, upload-time = "2025-05-19T14:15:09.825Z" }, + { url = "https://files.pythonhosted.org/packages/df/2a/e166d2ffbf4b10131b2d5b0e458f7cee7d986661caceae0de8753042d4b2/multidict-6.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:82ffabefc8d84c2742ad19c37f02cde5ec2a1ee172d19944d380f920a340e4b9", size = 64123, upload-time = "2025-05-19T14:15:11.044Z" }, + { url = "https://files.pythonhosted.org/packages/8c/96/e200e379ae5b6f95cbae472e0199ea98913f03d8c9a709f42612a432932c/multidict-6.4.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6a2f58a66fe2c22615ad26156354005391e26a2f3721c3621504cd87c1ea87bf", size = 38049, upload-time = "2025-05-19T14:15:12.902Z" }, + { url = "https://files.pythonhosted.org/packages/75/fb/47afd17b83f6a8c7fa863c6d23ac5ba6a0e6145ed8a6bcc8da20b2b2c1d2/multidict-6.4.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5883d6ee0fd9d8a48e9174df47540b7545909841ac82354c7ae4cbe9952603bd", size = 37078, upload-time = "2025-05-19T14:15:14.282Z" }, + { url = "https://files.pythonhosted.org/packages/fa/70/1af3143000eddfb19fd5ca5e78393985ed988ac493bb859800fe0914041f/multidict-6.4.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9abcf56a9511653fa1d052bfc55fbe53dbee8f34e68bd6a5a038731b0ca42d15", size = 224097, upload-time = "2025-05-19T14:15:15.566Z" }, + { url = "https://files.pythonhosted.org/packages/b1/39/d570c62b53d4fba844e0378ffbcd02ac25ca423d3235047013ba2f6f60f8/multidict-6.4.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6ed5ae5605d4ad5a049fad2a28bb7193400700ce2f4ae484ab702d1e3749c3f9", size = 230768, upload-time = "2025-05-19T14:15:17.308Z" }, + { url = "https://files.pythonhosted.org/packages/fd/f8/ed88f2c4d06f752b015933055eb291d9bc184936903752c66f68fb3c95a7/multidict-6.4.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbfcb60396f9bcfa63e017a180c3105b8c123a63e9d1428a36544e7d37ca9e20", size = 231331, upload-time = "2025-05-19T14:15:18.73Z" }, + { url = "https://files.pythonhosted.org/packages/9c/6f/8e07cffa32f483ab887b0d56bbd8747ac2c1acd00dc0af6fcf265f4a121e/multidict-6.4.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0f1987787f5f1e2076b59692352ab29a955b09ccc433c1f6b8e8e18666f608b", size = 230169, upload-time = "2025-05-19T14:15:20.179Z" }, + { url = "https://files.pythonhosted.org/packages/e6/2b/5dcf173be15e42f330110875a2668ddfc208afc4229097312212dc9c1236/multidict-6.4.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d0121ccce8c812047d8d43d691a1ad7641f72c4f730474878a5aeae1b8ead8c", size = 222947, upload-time = "2025-05-19T14:15:21.714Z" }, + { url = "https://files.pythonhosted.org/packages/39/75/4ddcbcebe5ebcd6faa770b629260d15840a5fc07ce8ad295a32e14993726/multidict-6.4.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ec4967114295b8afd120a8eec579920c882831a3e4c3331d591a8e5bfbbc0f", size = 215761, upload-time = "2025-05-19T14:15:23.242Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c9/55e998ae45ff15c5608e384206aa71a11e1b7f48b64d166db400b14a3433/multidict-6.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:995f985e2e268deaf17867801b859a282e0448633f1310e3704b30616d269d69", size = 227605, upload-time = "2025-05-19T14:15:24.763Z" }, + { url = "https://files.pythonhosted.org/packages/04/49/c2404eac74497503c77071bd2e6f88c7e94092b8a07601536b8dbe99be50/multidict-6.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:d832c608f94b9f92a0ec8b7e949be7792a642b6e535fcf32f3e28fab69eeb046", size = 226144, upload-time = "2025-05-19T14:15:26.249Z" }, + { url = "https://files.pythonhosted.org/packages/62/c5/0cd0c3c6f18864c40846aa2252cd69d308699cb163e1c0d989ca301684da/multidict-6.4.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d21c1212171cf7da703c5b0b7a0e85be23b720818aef502ad187d627316d5645", size = 221100, upload-time = "2025-05-19T14:15:28.303Z" }, + { url = "https://files.pythonhosted.org/packages/71/7b/f2f3887bea71739a046d601ef10e689528d4f911d84da873b6be9194ffea/multidict-6.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:cbebaa076aaecad3d4bb4c008ecc73b09274c952cf6a1b78ccfd689e51f5a5b0", size = 232731, upload-time = "2025-05-19T14:15:30.263Z" }, + { url = "https://files.pythonhosted.org/packages/e5/b3/d9de808349df97fa75ec1372758701b5800ebad3c46ae377ad63058fbcc6/multidict-6.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:c93a6fb06cc8e5d3628b2b5fda215a5db01e8f08fc15fadd65662d9b857acbe4", size = 229637, upload-time = "2025-05-19T14:15:33.337Z" }, + { url = "https://files.pythonhosted.org/packages/5e/57/13207c16b615eb4f1745b44806a96026ef8e1b694008a58226c2d8f5f0a5/multidict-6.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8cd8f81f1310182362fb0c7898145ea9c9b08a71081c5963b40ee3e3cac589b1", size = 225594, upload-time = "2025-05-19T14:15:34.832Z" }, + { url = "https://files.pythonhosted.org/packages/3a/e4/d23bec2f70221604f5565000632c305fc8f25ba953e8ce2d8a18842b9841/multidict-6.4.4-cp313-cp313-win32.whl", hash = "sha256:3e9f1cd61a0ab857154205fb0b1f3d3ace88d27ebd1409ab7af5096e409614cd", size = 35359, upload-time = "2025-05-19T14:15:36.246Z" }, + { url = "https://files.pythonhosted.org/packages/a7/7a/cfe1a47632be861b627f46f642c1d031704cc1c0f5c0efbde2ad44aa34bd/multidict-6.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:8ffb40b74400e4455785c2fa37eba434269149ec525fc8329858c862e4b35373", size = 38903, upload-time = "2025-05-19T14:15:37.507Z" }, + { url = "https://files.pythonhosted.org/packages/68/7b/15c259b0ab49938a0a1c8f3188572802704a779ddb294edc1b2a72252e7c/multidict-6.4.4-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:6a602151dbf177be2450ef38966f4be3467d41a86c6a845070d12e17c858a156", size = 68895, upload-time = "2025-05-19T14:15:38.856Z" }, + { url = "https://files.pythonhosted.org/packages/f1/7d/168b5b822bccd88142e0a3ce985858fea612404edd228698f5af691020c9/multidict-6.4.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0d2b9712211b860d123815a80b859075d86a4d54787e247d7fbee9db6832cf1c", size = 40183, upload-time = "2025-05-19T14:15:40.197Z" }, + { url = "https://files.pythonhosted.org/packages/e0/b7/d4b8d98eb850ef28a4922ba508c31d90715fd9b9da3801a30cea2967130b/multidict-6.4.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d2fa86af59f8fc1972e121ade052145f6da22758f6996a197d69bb52f8204e7e", size = 39592, upload-time = "2025-05-19T14:15:41.508Z" }, + { url = "https://files.pythonhosted.org/packages/18/28/a554678898a19583548e742080cf55d169733baf57efc48c2f0273a08583/multidict-6.4.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50855d03e9e4d66eab6947ba688ffb714616f985838077bc4b490e769e48da51", size = 226071, upload-time = "2025-05-19T14:15:42.877Z" }, + { url = "https://files.pythonhosted.org/packages/ee/dc/7ba6c789d05c310e294f85329efac1bf5b450338d2542498db1491a264df/multidict-6.4.4-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5bce06b83be23225be1905dcdb6b789064fae92499fbc458f59a8c0e68718601", size = 222597, upload-time = "2025-05-19T14:15:44.412Z" }, + { url = "https://files.pythonhosted.org/packages/24/4f/34eadbbf401b03768dba439be0fb94b0d187facae9142821a3d5599ccb3b/multidict-6.4.4-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66ed0731f8e5dfd8369a883b6e564aca085fb9289aacabd9decd70568b9a30de", size = 228253, upload-time = "2025-05-19T14:15:46.474Z" }, + { url = "https://files.pythonhosted.org/packages/c0/e6/493225a3cdb0d8d80d43a94503fc313536a07dae54a3f030d279e629a2bc/multidict-6.4.4-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:329ae97fc2f56f44d91bc47fe0972b1f52d21c4b7a2ac97040da02577e2daca2", size = 226146, upload-time = "2025-05-19T14:15:48.003Z" }, + { url = "https://files.pythonhosted.org/packages/2f/70/e411a7254dc3bff6f7e6e004303b1b0591358e9f0b7c08639941e0de8bd6/multidict-6.4.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c27e5dcf520923d6474d98b96749e6805f7677e93aaaf62656005b8643f907ab", size = 220585, upload-time = "2025-05-19T14:15:49.546Z" }, + { url = "https://files.pythonhosted.org/packages/08/8f/beb3ae7406a619100d2b1fb0022c3bb55a8225ab53c5663648ba50dfcd56/multidict-6.4.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:058cc59b9e9b143cc56715e59e22941a5d868c322242278d28123a5d09cdf6b0", size = 212080, upload-time = "2025-05-19T14:15:51.151Z" }, + { url = "https://files.pythonhosted.org/packages/9c/ec/355124e9d3d01cf8edb072fd14947220f357e1c5bc79c88dff89297e9342/multidict-6.4.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:69133376bc9a03f8c47343d33f91f74a99c339e8b58cea90433d8e24bb298031", size = 226558, upload-time = "2025-05-19T14:15:52.665Z" }, + { url = "https://files.pythonhosted.org/packages/fd/22/d2b95cbebbc2ada3be3812ea9287dcc9712d7f1a012fad041770afddb2ad/multidict-6.4.4-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:d6b15c55721b1b115c5ba178c77104123745b1417527ad9641a4c5e2047450f0", size = 212168, upload-time = "2025-05-19T14:15:55.279Z" }, + { url = "https://files.pythonhosted.org/packages/4d/c5/62bfc0b2f9ce88326dbe7179f9824a939c6c7775b23b95de777267b9725c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:a887b77f51d3d41e6e1a63cf3bc7ddf24de5939d9ff69441387dfefa58ac2e26", size = 217970, upload-time = "2025-05-19T14:15:56.806Z" }, + { url = "https://files.pythonhosted.org/packages/79/74/977cea1aadc43ff1c75d23bd5bc4768a8fac98c14e5878d6ee8d6bab743c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:632a3bf8f1787f7ef7d3c2f68a7bde5be2f702906f8b5842ad6da9d974d0aab3", size = 226980, upload-time = "2025-05-19T14:15:58.313Z" }, + { url = "https://files.pythonhosted.org/packages/48/fc/cc4a1a2049df2eb84006607dc428ff237af38e0fcecfdb8a29ca47b1566c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:a145c550900deb7540973c5cdb183b0d24bed6b80bf7bddf33ed8f569082535e", size = 220641, upload-time = "2025-05-19T14:15:59.866Z" }, + { url = "https://files.pythonhosted.org/packages/3b/6a/a7444d113ab918701988d4abdde373dbdfd2def7bd647207e2bf645c7eac/multidict-6.4.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc5d83c6619ca5c9672cb78b39ed8542f1975a803dee2cda114ff73cbb076edd", size = 221728, upload-time = "2025-05-19T14:16:01.535Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b0/fdf4c73ad1c55e0f4dbbf2aa59dd37037334091f9a4961646d2b7ac91a86/multidict-6.4.4-cp313-cp313t-win32.whl", hash = "sha256:3312f63261b9df49be9d57aaa6abf53a6ad96d93b24f9cc16cf979956355ce6e", size = 41913, upload-time = "2025-05-19T14:16:03.199Z" }, + { url = "https://files.pythonhosted.org/packages/8e/92/27989ecca97e542c0d01d05a98a5ae12198a243a9ee12563a0313291511f/multidict-6.4.4-cp313-cp313t-win_amd64.whl", hash = "sha256:ba852168d814b2c73333073e1c7116d9395bea69575a01b0b3c89d2d5a87c8fb", size = 46112, upload-time = "2025-05-19T14:16:04.909Z" }, + { url = "https://files.pythonhosted.org/packages/84/5d/e17845bb0fa76334477d5de38654d27946d5b5d3695443987a094a71b440/multidict-6.4.4-py3-none-any.whl", hash = "sha256:bd4557071b561a8b3b6075c3ce93cf9bfb6182cb241805c3d66ced3b75eff4ac", size = 10481, upload-time = "2025-05-19T14:16:36.024Z" }, ] [[package]] name = "packaging" version = "25.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727 } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469 }, + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, ] [[package]] @@ -1069,142 +1069,142 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "regex" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7b/91/abdc50c4ef06fdf8d047f60ee777ca9b2a7885e1a9cea81343fbecda52d7/parsimonious-0.10.0.tar.gz", hash = "sha256:8281600da180ec8ae35427a4ab4f7b82bfec1e3d1e52f80cb60ea82b9512501c", size = 52172 } +sdist = { url = "https://files.pythonhosted.org/packages/7b/91/abdc50c4ef06fdf8d047f60ee777ca9b2a7885e1a9cea81343fbecda52d7/parsimonious-0.10.0.tar.gz", hash = "sha256:8281600da180ec8ae35427a4ab4f7b82bfec1e3d1e52f80cb60ea82b9512501c", size = 52172, upload-time = "2022-09-03T17:01:17.004Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/aa/0f/c8b64d9b54ea631fcad4e9e3c8dbe8c11bb32a623be94f22974c88e71eaf/parsimonious-0.10.0-py3-none-any.whl", hash = "sha256:982ab435fabe86519b57f6b35610aa4e4e977e9f02a14353edf4bbc75369fc0f", size = 48427 }, + { url = "https://files.pythonhosted.org/packages/aa/0f/c8b64d9b54ea631fcad4e9e3c8dbe8c11bb32a623be94f22974c88e71eaf/parsimonious-0.10.0-py3-none-any.whl", hash = "sha256:982ab435fabe86519b57f6b35610aa4e4e977e9f02a14353edf4bbc75369fc0f", size = 48427, upload-time = "2022-09-03T17:01:13.814Z" }, ] [[package]] name = "pluggy" version = "1.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412 } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538 }, + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] [[package]] name = "propcache" version = "0.3.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a6/16/43264e4a779dd8588c21a70f0709665ee8f611211bdd2c87d952cfa7c776/propcache-0.3.2.tar.gz", hash = "sha256:20d7d62e4e7ef05f221e0db2856b979540686342e7dd9973b815599c7057e168", size = 44139 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ab/14/510deed325e262afeb8b360043c5d7c960da7d3ecd6d6f9496c9c56dc7f4/propcache-0.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:22d9962a358aedbb7a2e36187ff273adeaab9743373a272976d2e348d08c7770", size = 73178 }, - { url = "https://files.pythonhosted.org/packages/cd/4e/ad52a7925ff01c1325653a730c7ec3175a23f948f08626a534133427dcff/propcache-0.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0d0fda578d1dc3f77b6b5a5dce3b9ad69a8250a891760a548df850a5e8da87f3", size = 43133 }, - { url = "https://files.pythonhosted.org/packages/63/7c/e9399ba5da7780871db4eac178e9c2e204c23dd3e7d32df202092a1ed400/propcache-0.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3def3da3ac3ce41562d85db655d18ebac740cb3fa4367f11a52b3da9d03a5cc3", size = 43039 }, - { url = "https://files.pythonhosted.org/packages/22/e1/58da211eb8fdc6fc854002387d38f415a6ca5f5c67c1315b204a5d3e9d7a/propcache-0.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bec58347a5a6cebf239daba9bda37dffec5b8d2ce004d9fe4edef3d2815137e", size = 201903 }, - { url = "https://files.pythonhosted.org/packages/c4/0a/550ea0f52aac455cb90111c8bab995208443e46d925e51e2f6ebdf869525/propcache-0.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55ffda449a507e9fbd4aca1a7d9aa6753b07d6166140e5a18d2ac9bc49eac220", size = 213362 }, - { url = "https://files.pythonhosted.org/packages/5a/af/9893b7d878deda9bb69fcf54600b247fba7317761b7db11fede6e0f28bd0/propcache-0.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64a67fb39229a8a8491dd42f864e5e263155e729c2e7ff723d6e25f596b1e8cb", size = 210525 }, - { url = "https://files.pythonhosted.org/packages/7c/bb/38fd08b278ca85cde36d848091ad2b45954bc5f15cce494bb300b9285831/propcache-0.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9da1cf97b92b51253d5b68cf5a2b9e0dafca095e36b7f2da335e27dc6172a614", size = 198283 }, - { url = "https://files.pythonhosted.org/packages/78/8c/9fe55bd01d362bafb413dfe508c48753111a1e269737fa143ba85693592c/propcache-0.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5f559e127134b07425134b4065be45b166183fdcb433cb6c24c8e4149056ad50", size = 191872 }, - { url = "https://files.pythonhosted.org/packages/54/14/4701c33852937a22584e08abb531d654c8bcf7948a8f87ad0a4822394147/propcache-0.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aff2e4e06435d61f11a428360a932138d0ec288b0a31dd9bd78d200bd4a2b339", size = 199452 }, - { url = "https://files.pythonhosted.org/packages/16/44/447f2253d859602095356007657ee535e0093215ea0b3d1d6a41d16e5201/propcache-0.3.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:4927842833830942a5d0a56e6f4839bc484785b8e1ce8d287359794818633ba0", size = 191567 }, - { url = "https://files.pythonhosted.org/packages/f2/b3/e4756258749bb2d3b46defcff606a2f47410bab82be5824a67e84015b267/propcache-0.3.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6107ddd08b02654a30fb8ad7a132021759d750a82578b94cd55ee2772b6ebea2", size = 193015 }, - { url = "https://files.pythonhosted.org/packages/1e/df/e6d3c7574233164b6330b9fd697beeac402afd367280e6dc377bb99b43d9/propcache-0.3.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:70bd8b9cd6b519e12859c99f3fc9a93f375ebd22a50296c3a295028bea73b9e7", size = 204660 }, - { url = "https://files.pythonhosted.org/packages/b2/53/e4d31dd5170b4a0e2e6b730f2385a96410633b4833dc25fe5dffd1f73294/propcache-0.3.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2183111651d710d3097338dd1893fcf09c9f54e27ff1a8795495a16a469cc90b", size = 206105 }, - { url = "https://files.pythonhosted.org/packages/7f/fe/74d54cf9fbe2a20ff786e5f7afcfde446588f0cf15fb2daacfbc267b866c/propcache-0.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fb075ad271405dcad8e2a7ffc9a750a3bf70e533bd86e89f0603e607b93aa64c", size = 196980 }, - { url = "https://files.pythonhosted.org/packages/22/ec/c469c9d59dada8a7679625e0440b544fe72e99311a4679c279562051f6fc/propcache-0.3.2-cp310-cp310-win32.whl", hash = "sha256:404d70768080d3d3bdb41d0771037da19d8340d50b08e104ca0e7f9ce55fce70", size = 37679 }, - { url = "https://files.pythonhosted.org/packages/38/35/07a471371ac89d418f8d0b699c75ea6dca2041fbda360823de21f6a9ce0a/propcache-0.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:7435d766f978b4ede777002e6b3b6641dd229cd1da8d3d3106a45770365f9ad9", size = 41459 }, - { url = "https://files.pythonhosted.org/packages/80/8d/e8b436717ab9c2cfc23b116d2c297305aa4cd8339172a456d61ebf5669b8/propcache-0.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0b8d2f607bd8f80ddc04088bc2a037fdd17884a6fcadc47a96e334d72f3717be", size = 74207 }, - { url = "https://files.pythonhosted.org/packages/d6/29/1e34000e9766d112171764b9fa3226fa0153ab565d0c242c70e9945318a7/propcache-0.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06766d8f34733416e2e34f46fea488ad5d60726bb9481d3cddf89a6fa2d9603f", size = 43648 }, - { url = "https://files.pythonhosted.org/packages/46/92/1ad5af0df781e76988897da39b5f086c2bf0f028b7f9bd1f409bb05b6874/propcache-0.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2dc1f4a1df4fecf4e6f68013575ff4af84ef6f478fe5344317a65d38a8e6dc9", size = 43496 }, - { url = "https://files.pythonhosted.org/packages/b3/ce/e96392460f9fb68461fabab3e095cb00c8ddf901205be4eae5ce246e5b7e/propcache-0.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be29c4f4810c5789cf10ddf6af80b041c724e629fa51e308a7a0fb19ed1ef7bf", size = 217288 }, - { url = "https://files.pythonhosted.org/packages/c5/2a/866726ea345299f7ceefc861a5e782b045545ae6940851930a6adaf1fca6/propcache-0.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59d61f6970ecbd8ff2e9360304d5c8876a6abd4530cb752c06586849ac8a9dc9", size = 227456 }, - { url = "https://files.pythonhosted.org/packages/de/03/07d992ccb6d930398689187e1b3c718339a1c06b8b145a8d9650e4726166/propcache-0.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:62180e0b8dbb6b004baec00a7983e4cc52f5ada9cd11f48c3528d8cfa7b96a66", size = 225429 }, - { url = "https://files.pythonhosted.org/packages/5d/e6/116ba39448753b1330f48ab8ba927dcd6cf0baea8a0ccbc512dfb49ba670/propcache-0.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c144ca294a204c470f18cf4c9d78887810d04a3e2fbb30eea903575a779159df", size = 213472 }, - { url = "https://files.pythonhosted.org/packages/a6/85/f01f5d97e54e428885a5497ccf7f54404cbb4f906688a1690cd51bf597dc/propcache-0.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5c2a784234c28854878d68978265617aa6dc0780e53d44b4d67f3651a17a9a2", size = 204480 }, - { url = "https://files.pythonhosted.org/packages/e3/79/7bf5ab9033b8b8194cc3f7cf1aaa0e9c3256320726f64a3e1f113a812dce/propcache-0.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5745bc7acdafa978ca1642891b82c19238eadc78ba2aaa293c6863b304e552d7", size = 214530 }, - { url = "https://files.pythonhosted.org/packages/31/0b/bd3e0c00509b609317df4a18e6b05a450ef2d9a963e1d8bc9c9415d86f30/propcache-0.3.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:c0075bf773d66fa8c9d41f66cc132ecc75e5bb9dd7cce3cfd14adc5ca184cb95", size = 205230 }, - { url = "https://files.pythonhosted.org/packages/7a/23/fae0ff9b54b0de4e819bbe559508da132d5683c32d84d0dc2ccce3563ed4/propcache-0.3.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5f57aa0847730daceff0497f417c9de353c575d8da3579162cc74ac294c5369e", size = 206754 }, - { url = "https://files.pythonhosted.org/packages/b7/7f/ad6a3c22630aaa5f618b4dc3c3598974a72abb4c18e45a50b3cdd091eb2f/propcache-0.3.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:eef914c014bf72d18efb55619447e0aecd5fb7c2e3fa7441e2e5d6099bddff7e", size = 218430 }, - { url = "https://files.pythonhosted.org/packages/5b/2c/ba4f1c0e8a4b4c75910742f0d333759d441f65a1c7f34683b4a74c0ee015/propcache-0.3.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2a4092e8549031e82facf3decdbc0883755d5bbcc62d3aea9d9e185549936dcf", size = 223884 }, - { url = "https://files.pythonhosted.org/packages/88/e4/ebe30fc399e98572019eee82ad0caf512401661985cbd3da5e3140ffa1b0/propcache-0.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:85871b050f174bc0bfb437efbdb68aaf860611953ed12418e4361bc9c392749e", size = 211480 }, - { url = "https://files.pythonhosted.org/packages/96/0a/7d5260b914e01d1d0906f7f38af101f8d8ed0dc47426219eeaf05e8ea7c2/propcache-0.3.2-cp311-cp311-win32.whl", hash = "sha256:36c8d9b673ec57900c3554264e630d45980fd302458e4ac801802a7fd2ef7897", size = 37757 }, - { url = "https://files.pythonhosted.org/packages/e1/2d/89fe4489a884bc0da0c3278c552bd4ffe06a1ace559db5ef02ef24ab446b/propcache-0.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53af8cb6a781b02d2ea079b5b853ba9430fcbe18a8e3ce647d5982a3ff69f39", size = 41500 }, - { url = "https://files.pythonhosted.org/packages/a8/42/9ca01b0a6f48e81615dca4765a8f1dd2c057e0540f6116a27dc5ee01dfb6/propcache-0.3.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8de106b6c84506b31c27168582cd3cb3000a6412c16df14a8628e5871ff83c10", size = 73674 }, - { url = "https://files.pythonhosted.org/packages/af/6e/21293133beb550f9c901bbece755d582bfaf2176bee4774000bd4dd41884/propcache-0.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:28710b0d3975117239c76600ea351934ac7b5ff56e60953474342608dbbb6154", size = 43570 }, - { url = "https://files.pythonhosted.org/packages/0c/c8/0393a0a3a2b8760eb3bde3c147f62b20044f0ddac81e9d6ed7318ec0d852/propcache-0.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce26862344bdf836650ed2487c3d724b00fbfec4233a1013f597b78c1cb73615", size = 43094 }, - { url = "https://files.pythonhosted.org/packages/37/2c/489afe311a690399d04a3e03b069225670c1d489eb7b044a566511c1c498/propcache-0.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bca54bd347a253af2cf4544bbec232ab982f4868de0dd684246b67a51bc6b1db", size = 226958 }, - { url = "https://files.pythonhosted.org/packages/9d/ca/63b520d2f3d418c968bf596839ae26cf7f87bead026b6192d4da6a08c467/propcache-0.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55780d5e9a2ddc59711d727226bb1ba83a22dd32f64ee15594b9392b1f544eb1", size = 234894 }, - { url = "https://files.pythonhosted.org/packages/11/60/1d0ed6fff455a028d678df30cc28dcee7af77fa2b0e6962ce1df95c9a2a9/propcache-0.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:035e631be25d6975ed87ab23153db6a73426a48db688070d925aa27e996fe93c", size = 233672 }, - { url = "https://files.pythonhosted.org/packages/37/7c/54fd5301ef38505ab235d98827207176a5c9b2aa61939b10a460ca53e123/propcache-0.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee6f22b6eaa39297c751d0e80c0d3a454f112f5c6481214fcf4c092074cecd67", size = 224395 }, - { url = "https://files.pythonhosted.org/packages/ee/1a/89a40e0846f5de05fdc6779883bf46ba980e6df4d2ff8fb02643de126592/propcache-0.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ca3aee1aa955438c4dba34fc20a9f390e4c79967257d830f137bd5a8a32ed3b", size = 212510 }, - { url = "https://files.pythonhosted.org/packages/5e/33/ca98368586c9566a6b8d5ef66e30484f8da84c0aac3f2d9aec6d31a11bd5/propcache-0.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7a4f30862869fa2b68380d677cc1c5fcf1e0f2b9ea0cf665812895c75d0ca3b8", size = 222949 }, - { url = "https://files.pythonhosted.org/packages/ba/11/ace870d0aafe443b33b2f0b7efdb872b7c3abd505bfb4890716ad7865e9d/propcache-0.3.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b77ec3c257d7816d9f3700013639db7491a434644c906a2578a11daf13176251", size = 217258 }, - { url = "https://files.pythonhosted.org/packages/5b/d2/86fd6f7adffcfc74b42c10a6b7db721d1d9ca1055c45d39a1a8f2a740a21/propcache-0.3.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:cab90ac9d3f14b2d5050928483d3d3b8fb6b4018893fc75710e6aa361ecb2474", size = 213036 }, - { url = "https://files.pythonhosted.org/packages/07/94/2d7d1e328f45ff34a0a284cf5a2847013701e24c2a53117e7c280a4316b3/propcache-0.3.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0b504d29f3c47cf6b9e936c1852246c83d450e8e063d50562115a6be6d3a2535", size = 227684 }, - { url = "https://files.pythonhosted.org/packages/b7/05/37ae63a0087677e90b1d14710e532ff104d44bc1efa3b3970fff99b891dc/propcache-0.3.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:ce2ac2675a6aa41ddb2a0c9cbff53780a617ac3d43e620f8fd77ba1c84dcfc06", size = 234562 }, - { url = "https://files.pythonhosted.org/packages/a4/7c/3f539fcae630408d0bd8bf3208b9a647ccad10976eda62402a80adf8fc34/propcache-0.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:62b4239611205294cc433845b914131b2a1f03500ff3c1ed093ed216b82621e1", size = 222142 }, - { url = "https://files.pythonhosted.org/packages/7c/d2/34b9eac8c35f79f8a962546b3e97e9d4b990c420ee66ac8255d5d9611648/propcache-0.3.2-cp312-cp312-win32.whl", hash = "sha256:df4a81b9b53449ebc90cc4deefb052c1dd934ba85012aa912c7ea7b7e38b60c1", size = 37711 }, - { url = "https://files.pythonhosted.org/packages/19/61/d582be5d226cf79071681d1b46b848d6cb03d7b70af7063e33a2787eaa03/propcache-0.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7046e79b989d7fe457bb755844019e10f693752d169076138abf17f31380800c", size = 41479 }, - { url = "https://files.pythonhosted.org/packages/dc/d1/8c747fafa558c603c4ca19d8e20b288aa0c7cda74e9402f50f31eb65267e/propcache-0.3.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ca592ed634a73ca002967458187109265e980422116c0a107cf93d81f95af945", size = 71286 }, - { url = "https://files.pythonhosted.org/packages/61/99/d606cb7986b60d89c36de8a85d58764323b3a5ff07770a99d8e993b3fa73/propcache-0.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9ecb0aad4020e275652ba3975740f241bd12a61f1a784df044cf7477a02bc252", size = 42425 }, - { url = "https://files.pythonhosted.org/packages/8c/96/ef98f91bbb42b79e9bb82bdd348b255eb9d65f14dbbe3b1594644c4073f7/propcache-0.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7f08f1cc28bd2eade7a8a3d2954ccc673bb02062e3e7da09bc75d843386b342f", size = 41846 }, - { url = "https://files.pythonhosted.org/packages/5b/ad/3f0f9a705fb630d175146cd7b1d2bf5555c9beaed54e94132b21aac098a6/propcache-0.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1a342c834734edb4be5ecb1e9fb48cb64b1e2320fccbd8c54bf8da8f2a84c33", size = 208871 }, - { url = "https://files.pythonhosted.org/packages/3a/38/2085cda93d2c8b6ec3e92af2c89489a36a5886b712a34ab25de9fbca7992/propcache-0.3.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a544caaae1ac73f1fecfae70ded3e93728831affebd017d53449e3ac052ac1e", size = 215720 }, - { url = "https://files.pythonhosted.org/packages/61/c1/d72ea2dc83ac7f2c8e182786ab0fc2c7bd123a1ff9b7975bee671866fe5f/propcache-0.3.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:310d11aa44635298397db47a3ebce7db99a4cc4b9bbdfcf6c98a60c8d5261cf1", size = 215203 }, - { url = "https://files.pythonhosted.org/packages/af/81/b324c44ae60c56ef12007105f1460d5c304b0626ab0cc6b07c8f2a9aa0b8/propcache-0.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c1396592321ac83157ac03a2023aa6cc4a3cc3cfdecb71090054c09e5a7cce3", size = 206365 }, - { url = "https://files.pythonhosted.org/packages/09/73/88549128bb89e66d2aff242488f62869014ae092db63ccea53c1cc75a81d/propcache-0.3.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cabf5b5902272565e78197edb682017d21cf3b550ba0460ee473753f28d23c1", size = 196016 }, - { url = "https://files.pythonhosted.org/packages/b9/3f/3bdd14e737d145114a5eb83cb172903afba7242f67c5877f9909a20d948d/propcache-0.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0a2f2235ac46a7aa25bdeb03a9e7060f6ecbd213b1f9101c43b3090ffb971ef6", size = 205596 }, - { url = "https://files.pythonhosted.org/packages/0f/ca/2f4aa819c357d3107c3763d7ef42c03980f9ed5c48c82e01e25945d437c1/propcache-0.3.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:92b69e12e34869a6970fd2f3da91669899994b47c98f5d430b781c26f1d9f387", size = 200977 }, - { url = "https://files.pythonhosted.org/packages/cd/4a/e65276c7477533c59085251ae88505caf6831c0e85ff8b2e31ebcbb949b1/propcache-0.3.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:54e02207c79968ebbdffc169591009f4474dde3b4679e16634d34c9363ff56b4", size = 197220 }, - { url = "https://files.pythonhosted.org/packages/7c/54/fc7152e517cf5578278b242396ce4d4b36795423988ef39bb8cd5bf274c8/propcache-0.3.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4adfb44cb588001f68c5466579d3f1157ca07f7504fc91ec87862e2b8e556b88", size = 210642 }, - { url = "https://files.pythonhosted.org/packages/b9/80/abeb4a896d2767bf5f1ea7b92eb7be6a5330645bd7fb844049c0e4045d9d/propcache-0.3.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fd3e6019dc1261cd0291ee8919dd91fbab7b169bb76aeef6c716833a3f65d206", size = 212789 }, - { url = "https://files.pythonhosted.org/packages/b3/db/ea12a49aa7b2b6d68a5da8293dcf50068d48d088100ac016ad92a6a780e6/propcache-0.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4c181cad81158d71c41a2bce88edce078458e2dd5ffee7eddd6b05da85079f43", size = 205880 }, - { url = "https://files.pythonhosted.org/packages/d1/e5/9076a0bbbfb65d1198007059c65639dfd56266cf8e477a9707e4b1999ff4/propcache-0.3.2-cp313-cp313-win32.whl", hash = "sha256:8a08154613f2249519e549de2330cf8e2071c2887309a7b07fb56098f5170a02", size = 37220 }, - { url = "https://files.pythonhosted.org/packages/d3/f5/b369e026b09a26cd77aa88d8fffd69141d2ae00a2abaaf5380d2603f4b7f/propcache-0.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:e41671f1594fc4ab0a6dec1351864713cb3a279910ae8b58f884a88a0a632c05", size = 40678 }, - { url = "https://files.pythonhosted.org/packages/a4/3a/6ece377b55544941a08d03581c7bc400a3c8cd3c2865900a68d5de79e21f/propcache-0.3.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:9a3cf035bbaf035f109987d9d55dc90e4b0e36e04bbbb95af3055ef17194057b", size = 76560 }, - { url = "https://files.pythonhosted.org/packages/0c/da/64a2bb16418740fa634b0e9c3d29edff1db07f56d3546ca2d86ddf0305e1/propcache-0.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:156c03d07dc1323d8dacaa221fbe028c5c70d16709cdd63502778e6c3ccca1b0", size = 44676 }, - { url = "https://files.pythonhosted.org/packages/36/7b/f025e06ea51cb72c52fb87e9b395cced02786610b60a3ed51da8af017170/propcache-0.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74413c0ba02ba86f55cf60d18daab219f7e531620c15f1e23d95563f505efe7e", size = 44701 }, - { url = "https://files.pythonhosted.org/packages/a4/00/faa1b1b7c3b74fc277f8642f32a4c72ba1d7b2de36d7cdfb676db7f4303e/propcache-0.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f066b437bb3fa39c58ff97ab2ca351db465157d68ed0440abecb21715eb24b28", size = 276934 }, - { url = "https://files.pythonhosted.org/packages/74/ab/935beb6f1756e0476a4d5938ff44bf0d13a055fed880caf93859b4f1baf4/propcache-0.3.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1304b085c83067914721e7e9d9917d41ad87696bf70f0bc7dee450e9c71ad0a", size = 278316 }, - { url = "https://files.pythonhosted.org/packages/f8/9d/994a5c1ce4389610838d1caec74bdf0e98b306c70314d46dbe4fcf21a3e2/propcache-0.3.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab50cef01b372763a13333b4e54021bdcb291fc9a8e2ccb9c2df98be51bcde6c", size = 282619 }, - { url = "https://files.pythonhosted.org/packages/2b/00/a10afce3d1ed0287cef2e09506d3be9822513f2c1e96457ee369adb9a6cd/propcache-0.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fad3b2a085ec259ad2c2842666b2a0a49dea8463579c606426128925af1ed725", size = 265896 }, - { url = "https://files.pythonhosted.org/packages/2e/a8/2aa6716ffa566ca57c749edb909ad27884680887d68517e4be41b02299f3/propcache-0.3.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:261fa020c1c14deafd54c76b014956e2f86991af198c51139faf41c4d5e83892", size = 252111 }, - { url = "https://files.pythonhosted.org/packages/36/4f/345ca9183b85ac29c8694b0941f7484bf419c7f0fea2d1e386b4f7893eed/propcache-0.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:46d7f8aa79c927e5f987ee3a80205c987717d3659f035c85cf0c3680526bdb44", size = 268334 }, - { url = "https://files.pythonhosted.org/packages/3e/ca/fcd54f78b59e3f97b3b9715501e3147f5340167733d27db423aa321e7148/propcache-0.3.2-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:6d8f3f0eebf73e3c0ff0e7853f68be638b4043c65a70517bb575eff54edd8dbe", size = 255026 }, - { url = "https://files.pythonhosted.org/packages/8b/95/8e6a6bbbd78ac89c30c225210a5c687790e532ba4088afb8c0445b77ef37/propcache-0.3.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:03c89c1b14a5452cf15403e291c0ccd7751d5b9736ecb2c5bab977ad6c5bcd81", size = 250724 }, - { url = "https://files.pythonhosted.org/packages/ee/b0/0dd03616142baba28e8b2d14ce5df6631b4673850a3d4f9c0f9dd714a404/propcache-0.3.2-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:0cc17efde71e12bbaad086d679ce575268d70bc123a5a71ea7ad76f70ba30bba", size = 268868 }, - { url = "https://files.pythonhosted.org/packages/c5/98/2c12407a7e4fbacd94ddd32f3b1e3d5231e77c30ef7162b12a60e2dd5ce3/propcache-0.3.2-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:acdf05d00696bc0447e278bb53cb04ca72354e562cf88ea6f9107df8e7fd9770", size = 271322 }, - { url = "https://files.pythonhosted.org/packages/35/91/9cb56efbb428b006bb85db28591e40b7736847b8331d43fe335acf95f6c8/propcache-0.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4445542398bd0b5d32df908031cb1b30d43ac848e20470a878b770ec2dcc6330", size = 265778 }, - { url = "https://files.pythonhosted.org/packages/9a/4c/b0fe775a2bdd01e176b14b574be679d84fc83958335790f7c9a686c1f468/propcache-0.3.2-cp313-cp313t-win32.whl", hash = "sha256:f86e5d7cd03afb3a1db8e9f9f6eff15794e79e791350ac48a8c924e6f439f394", size = 41175 }, - { url = "https://files.pythonhosted.org/packages/a4/ff/47f08595e3d9b5e149c150f88d9714574f1a7cbd89fe2817158a952674bf/propcache-0.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:9704bedf6e7cbe3c65eca4379a9b53ee6a83749f047808cbb5044d40d7d72198", size = 44857 }, - { url = "https://files.pythonhosted.org/packages/cc/35/cc0aaecf278bb4575b8555f2b137de5ab821595ddae9da9d3cd1da4072c7/propcache-0.3.2-py3-none-any.whl", hash = "sha256:98f1ec44fb675f5052cccc8e609c46ed23a35a1cfd18545ad4e29002d858a43f", size = 12663 }, +sdist = { url = "https://files.pythonhosted.org/packages/a6/16/43264e4a779dd8588c21a70f0709665ee8f611211bdd2c87d952cfa7c776/propcache-0.3.2.tar.gz", hash = "sha256:20d7d62e4e7ef05f221e0db2856b979540686342e7dd9973b815599c7057e168", size = 44139, upload-time = "2025-06-09T22:56:06.081Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/14/510deed325e262afeb8b360043c5d7c960da7d3ecd6d6f9496c9c56dc7f4/propcache-0.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:22d9962a358aedbb7a2e36187ff273adeaab9743373a272976d2e348d08c7770", size = 73178, upload-time = "2025-06-09T22:53:40.126Z" }, + { url = "https://files.pythonhosted.org/packages/cd/4e/ad52a7925ff01c1325653a730c7ec3175a23f948f08626a534133427dcff/propcache-0.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0d0fda578d1dc3f77b6b5a5dce3b9ad69a8250a891760a548df850a5e8da87f3", size = 43133, upload-time = "2025-06-09T22:53:41.965Z" }, + { url = "https://files.pythonhosted.org/packages/63/7c/e9399ba5da7780871db4eac178e9c2e204c23dd3e7d32df202092a1ed400/propcache-0.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3def3da3ac3ce41562d85db655d18ebac740cb3fa4367f11a52b3da9d03a5cc3", size = 43039, upload-time = "2025-06-09T22:53:43.268Z" }, + { url = "https://files.pythonhosted.org/packages/22/e1/58da211eb8fdc6fc854002387d38f415a6ca5f5c67c1315b204a5d3e9d7a/propcache-0.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bec58347a5a6cebf239daba9bda37dffec5b8d2ce004d9fe4edef3d2815137e", size = 201903, upload-time = "2025-06-09T22:53:44.872Z" }, + { url = "https://files.pythonhosted.org/packages/c4/0a/550ea0f52aac455cb90111c8bab995208443e46d925e51e2f6ebdf869525/propcache-0.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55ffda449a507e9fbd4aca1a7d9aa6753b07d6166140e5a18d2ac9bc49eac220", size = 213362, upload-time = "2025-06-09T22:53:46.707Z" }, + { url = "https://files.pythonhosted.org/packages/5a/af/9893b7d878deda9bb69fcf54600b247fba7317761b7db11fede6e0f28bd0/propcache-0.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64a67fb39229a8a8491dd42f864e5e263155e729c2e7ff723d6e25f596b1e8cb", size = 210525, upload-time = "2025-06-09T22:53:48.547Z" }, + { url = "https://files.pythonhosted.org/packages/7c/bb/38fd08b278ca85cde36d848091ad2b45954bc5f15cce494bb300b9285831/propcache-0.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9da1cf97b92b51253d5b68cf5a2b9e0dafca095e36b7f2da335e27dc6172a614", size = 198283, upload-time = "2025-06-09T22:53:50.067Z" }, + { url = "https://files.pythonhosted.org/packages/78/8c/9fe55bd01d362bafb413dfe508c48753111a1e269737fa143ba85693592c/propcache-0.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5f559e127134b07425134b4065be45b166183fdcb433cb6c24c8e4149056ad50", size = 191872, upload-time = "2025-06-09T22:53:51.438Z" }, + { url = "https://files.pythonhosted.org/packages/54/14/4701c33852937a22584e08abb531d654c8bcf7948a8f87ad0a4822394147/propcache-0.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aff2e4e06435d61f11a428360a932138d0ec288b0a31dd9bd78d200bd4a2b339", size = 199452, upload-time = "2025-06-09T22:53:53.229Z" }, + { url = "https://files.pythonhosted.org/packages/16/44/447f2253d859602095356007657ee535e0093215ea0b3d1d6a41d16e5201/propcache-0.3.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:4927842833830942a5d0a56e6f4839bc484785b8e1ce8d287359794818633ba0", size = 191567, upload-time = "2025-06-09T22:53:54.541Z" }, + { url = "https://files.pythonhosted.org/packages/f2/b3/e4756258749bb2d3b46defcff606a2f47410bab82be5824a67e84015b267/propcache-0.3.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6107ddd08b02654a30fb8ad7a132021759d750a82578b94cd55ee2772b6ebea2", size = 193015, upload-time = "2025-06-09T22:53:56.44Z" }, + { url = "https://files.pythonhosted.org/packages/1e/df/e6d3c7574233164b6330b9fd697beeac402afd367280e6dc377bb99b43d9/propcache-0.3.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:70bd8b9cd6b519e12859c99f3fc9a93f375ebd22a50296c3a295028bea73b9e7", size = 204660, upload-time = "2025-06-09T22:53:57.839Z" }, + { url = "https://files.pythonhosted.org/packages/b2/53/e4d31dd5170b4a0e2e6b730f2385a96410633b4833dc25fe5dffd1f73294/propcache-0.3.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2183111651d710d3097338dd1893fcf09c9f54e27ff1a8795495a16a469cc90b", size = 206105, upload-time = "2025-06-09T22:53:59.638Z" }, + { url = "https://files.pythonhosted.org/packages/7f/fe/74d54cf9fbe2a20ff786e5f7afcfde446588f0cf15fb2daacfbc267b866c/propcache-0.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fb075ad271405dcad8e2a7ffc9a750a3bf70e533bd86e89f0603e607b93aa64c", size = 196980, upload-time = "2025-06-09T22:54:01.071Z" }, + { url = "https://files.pythonhosted.org/packages/22/ec/c469c9d59dada8a7679625e0440b544fe72e99311a4679c279562051f6fc/propcache-0.3.2-cp310-cp310-win32.whl", hash = "sha256:404d70768080d3d3bdb41d0771037da19d8340d50b08e104ca0e7f9ce55fce70", size = 37679, upload-time = "2025-06-09T22:54:03.003Z" }, + { url = "https://files.pythonhosted.org/packages/38/35/07a471371ac89d418f8d0b699c75ea6dca2041fbda360823de21f6a9ce0a/propcache-0.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:7435d766f978b4ede777002e6b3b6641dd229cd1da8d3d3106a45770365f9ad9", size = 41459, upload-time = "2025-06-09T22:54:04.134Z" }, + { url = "https://files.pythonhosted.org/packages/80/8d/e8b436717ab9c2cfc23b116d2c297305aa4cd8339172a456d61ebf5669b8/propcache-0.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0b8d2f607bd8f80ddc04088bc2a037fdd17884a6fcadc47a96e334d72f3717be", size = 74207, upload-time = "2025-06-09T22:54:05.399Z" }, + { url = "https://files.pythonhosted.org/packages/d6/29/1e34000e9766d112171764b9fa3226fa0153ab565d0c242c70e9945318a7/propcache-0.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06766d8f34733416e2e34f46fea488ad5d60726bb9481d3cddf89a6fa2d9603f", size = 43648, upload-time = "2025-06-09T22:54:08.023Z" }, + { url = "https://files.pythonhosted.org/packages/46/92/1ad5af0df781e76988897da39b5f086c2bf0f028b7f9bd1f409bb05b6874/propcache-0.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2dc1f4a1df4fecf4e6f68013575ff4af84ef6f478fe5344317a65d38a8e6dc9", size = 43496, upload-time = "2025-06-09T22:54:09.228Z" }, + { url = "https://files.pythonhosted.org/packages/b3/ce/e96392460f9fb68461fabab3e095cb00c8ddf901205be4eae5ce246e5b7e/propcache-0.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be29c4f4810c5789cf10ddf6af80b041c724e629fa51e308a7a0fb19ed1ef7bf", size = 217288, upload-time = "2025-06-09T22:54:10.466Z" }, + { url = "https://files.pythonhosted.org/packages/c5/2a/866726ea345299f7ceefc861a5e782b045545ae6940851930a6adaf1fca6/propcache-0.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59d61f6970ecbd8ff2e9360304d5c8876a6abd4530cb752c06586849ac8a9dc9", size = 227456, upload-time = "2025-06-09T22:54:11.828Z" }, + { url = "https://files.pythonhosted.org/packages/de/03/07d992ccb6d930398689187e1b3c718339a1c06b8b145a8d9650e4726166/propcache-0.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:62180e0b8dbb6b004baec00a7983e4cc52f5ada9cd11f48c3528d8cfa7b96a66", size = 225429, upload-time = "2025-06-09T22:54:13.823Z" }, + { url = "https://files.pythonhosted.org/packages/5d/e6/116ba39448753b1330f48ab8ba927dcd6cf0baea8a0ccbc512dfb49ba670/propcache-0.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c144ca294a204c470f18cf4c9d78887810d04a3e2fbb30eea903575a779159df", size = 213472, upload-time = "2025-06-09T22:54:15.232Z" }, + { url = "https://files.pythonhosted.org/packages/a6/85/f01f5d97e54e428885a5497ccf7f54404cbb4f906688a1690cd51bf597dc/propcache-0.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5c2a784234c28854878d68978265617aa6dc0780e53d44b4d67f3651a17a9a2", size = 204480, upload-time = "2025-06-09T22:54:17.104Z" }, + { url = "https://files.pythonhosted.org/packages/e3/79/7bf5ab9033b8b8194cc3f7cf1aaa0e9c3256320726f64a3e1f113a812dce/propcache-0.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5745bc7acdafa978ca1642891b82c19238eadc78ba2aaa293c6863b304e552d7", size = 214530, upload-time = "2025-06-09T22:54:18.512Z" }, + { url = "https://files.pythonhosted.org/packages/31/0b/bd3e0c00509b609317df4a18e6b05a450ef2d9a963e1d8bc9c9415d86f30/propcache-0.3.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:c0075bf773d66fa8c9d41f66cc132ecc75e5bb9dd7cce3cfd14adc5ca184cb95", size = 205230, upload-time = "2025-06-09T22:54:19.947Z" }, + { url = "https://files.pythonhosted.org/packages/7a/23/fae0ff9b54b0de4e819bbe559508da132d5683c32d84d0dc2ccce3563ed4/propcache-0.3.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5f57aa0847730daceff0497f417c9de353c575d8da3579162cc74ac294c5369e", size = 206754, upload-time = "2025-06-09T22:54:21.716Z" }, + { url = "https://files.pythonhosted.org/packages/b7/7f/ad6a3c22630aaa5f618b4dc3c3598974a72abb4c18e45a50b3cdd091eb2f/propcache-0.3.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:eef914c014bf72d18efb55619447e0aecd5fb7c2e3fa7441e2e5d6099bddff7e", size = 218430, upload-time = "2025-06-09T22:54:23.17Z" }, + { url = "https://files.pythonhosted.org/packages/5b/2c/ba4f1c0e8a4b4c75910742f0d333759d441f65a1c7f34683b4a74c0ee015/propcache-0.3.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2a4092e8549031e82facf3decdbc0883755d5bbcc62d3aea9d9e185549936dcf", size = 223884, upload-time = "2025-06-09T22:54:25.539Z" }, + { url = "https://files.pythonhosted.org/packages/88/e4/ebe30fc399e98572019eee82ad0caf512401661985cbd3da5e3140ffa1b0/propcache-0.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:85871b050f174bc0bfb437efbdb68aaf860611953ed12418e4361bc9c392749e", size = 211480, upload-time = "2025-06-09T22:54:26.892Z" }, + { url = "https://files.pythonhosted.org/packages/96/0a/7d5260b914e01d1d0906f7f38af101f8d8ed0dc47426219eeaf05e8ea7c2/propcache-0.3.2-cp311-cp311-win32.whl", hash = "sha256:36c8d9b673ec57900c3554264e630d45980fd302458e4ac801802a7fd2ef7897", size = 37757, upload-time = "2025-06-09T22:54:28.241Z" }, + { url = "https://files.pythonhosted.org/packages/e1/2d/89fe4489a884bc0da0c3278c552bd4ffe06a1ace559db5ef02ef24ab446b/propcache-0.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53af8cb6a781b02d2ea079b5b853ba9430fcbe18a8e3ce647d5982a3ff69f39", size = 41500, upload-time = "2025-06-09T22:54:29.4Z" }, + { url = "https://files.pythonhosted.org/packages/a8/42/9ca01b0a6f48e81615dca4765a8f1dd2c057e0540f6116a27dc5ee01dfb6/propcache-0.3.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8de106b6c84506b31c27168582cd3cb3000a6412c16df14a8628e5871ff83c10", size = 73674, upload-time = "2025-06-09T22:54:30.551Z" }, + { url = "https://files.pythonhosted.org/packages/af/6e/21293133beb550f9c901bbece755d582bfaf2176bee4774000bd4dd41884/propcache-0.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:28710b0d3975117239c76600ea351934ac7b5ff56e60953474342608dbbb6154", size = 43570, upload-time = "2025-06-09T22:54:32.296Z" }, + { url = "https://files.pythonhosted.org/packages/0c/c8/0393a0a3a2b8760eb3bde3c147f62b20044f0ddac81e9d6ed7318ec0d852/propcache-0.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce26862344bdf836650ed2487c3d724b00fbfec4233a1013f597b78c1cb73615", size = 43094, upload-time = "2025-06-09T22:54:33.929Z" }, + { url = "https://files.pythonhosted.org/packages/37/2c/489afe311a690399d04a3e03b069225670c1d489eb7b044a566511c1c498/propcache-0.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bca54bd347a253af2cf4544bbec232ab982f4868de0dd684246b67a51bc6b1db", size = 226958, upload-time = "2025-06-09T22:54:35.186Z" }, + { url = "https://files.pythonhosted.org/packages/9d/ca/63b520d2f3d418c968bf596839ae26cf7f87bead026b6192d4da6a08c467/propcache-0.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55780d5e9a2ddc59711d727226bb1ba83a22dd32f64ee15594b9392b1f544eb1", size = 234894, upload-time = "2025-06-09T22:54:36.708Z" }, + { url = "https://files.pythonhosted.org/packages/11/60/1d0ed6fff455a028d678df30cc28dcee7af77fa2b0e6962ce1df95c9a2a9/propcache-0.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:035e631be25d6975ed87ab23153db6a73426a48db688070d925aa27e996fe93c", size = 233672, upload-time = "2025-06-09T22:54:38.062Z" }, + { url = "https://files.pythonhosted.org/packages/37/7c/54fd5301ef38505ab235d98827207176a5c9b2aa61939b10a460ca53e123/propcache-0.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee6f22b6eaa39297c751d0e80c0d3a454f112f5c6481214fcf4c092074cecd67", size = 224395, upload-time = "2025-06-09T22:54:39.634Z" }, + { url = "https://files.pythonhosted.org/packages/ee/1a/89a40e0846f5de05fdc6779883bf46ba980e6df4d2ff8fb02643de126592/propcache-0.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ca3aee1aa955438c4dba34fc20a9f390e4c79967257d830f137bd5a8a32ed3b", size = 212510, upload-time = "2025-06-09T22:54:41.565Z" }, + { url = "https://files.pythonhosted.org/packages/5e/33/ca98368586c9566a6b8d5ef66e30484f8da84c0aac3f2d9aec6d31a11bd5/propcache-0.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7a4f30862869fa2b68380d677cc1c5fcf1e0f2b9ea0cf665812895c75d0ca3b8", size = 222949, upload-time = "2025-06-09T22:54:43.038Z" }, + { url = "https://files.pythonhosted.org/packages/ba/11/ace870d0aafe443b33b2f0b7efdb872b7c3abd505bfb4890716ad7865e9d/propcache-0.3.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b77ec3c257d7816d9f3700013639db7491a434644c906a2578a11daf13176251", size = 217258, upload-time = "2025-06-09T22:54:44.376Z" }, + { url = "https://files.pythonhosted.org/packages/5b/d2/86fd6f7adffcfc74b42c10a6b7db721d1d9ca1055c45d39a1a8f2a740a21/propcache-0.3.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:cab90ac9d3f14b2d5050928483d3d3b8fb6b4018893fc75710e6aa361ecb2474", size = 213036, upload-time = "2025-06-09T22:54:46.243Z" }, + { url = "https://files.pythonhosted.org/packages/07/94/2d7d1e328f45ff34a0a284cf5a2847013701e24c2a53117e7c280a4316b3/propcache-0.3.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0b504d29f3c47cf6b9e936c1852246c83d450e8e063d50562115a6be6d3a2535", size = 227684, upload-time = "2025-06-09T22:54:47.63Z" }, + { url = "https://files.pythonhosted.org/packages/b7/05/37ae63a0087677e90b1d14710e532ff104d44bc1efa3b3970fff99b891dc/propcache-0.3.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:ce2ac2675a6aa41ddb2a0c9cbff53780a617ac3d43e620f8fd77ba1c84dcfc06", size = 234562, upload-time = "2025-06-09T22:54:48.982Z" }, + { url = "https://files.pythonhosted.org/packages/a4/7c/3f539fcae630408d0bd8bf3208b9a647ccad10976eda62402a80adf8fc34/propcache-0.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:62b4239611205294cc433845b914131b2a1f03500ff3c1ed093ed216b82621e1", size = 222142, upload-time = "2025-06-09T22:54:50.424Z" }, + { url = "https://files.pythonhosted.org/packages/7c/d2/34b9eac8c35f79f8a962546b3e97e9d4b990c420ee66ac8255d5d9611648/propcache-0.3.2-cp312-cp312-win32.whl", hash = "sha256:df4a81b9b53449ebc90cc4deefb052c1dd934ba85012aa912c7ea7b7e38b60c1", size = 37711, upload-time = "2025-06-09T22:54:52.072Z" }, + { url = "https://files.pythonhosted.org/packages/19/61/d582be5d226cf79071681d1b46b848d6cb03d7b70af7063e33a2787eaa03/propcache-0.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7046e79b989d7fe457bb755844019e10f693752d169076138abf17f31380800c", size = 41479, upload-time = "2025-06-09T22:54:53.234Z" }, + { url = "https://files.pythonhosted.org/packages/dc/d1/8c747fafa558c603c4ca19d8e20b288aa0c7cda74e9402f50f31eb65267e/propcache-0.3.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ca592ed634a73ca002967458187109265e980422116c0a107cf93d81f95af945", size = 71286, upload-time = "2025-06-09T22:54:54.369Z" }, + { url = "https://files.pythonhosted.org/packages/61/99/d606cb7986b60d89c36de8a85d58764323b3a5ff07770a99d8e993b3fa73/propcache-0.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9ecb0aad4020e275652ba3975740f241bd12a61f1a784df044cf7477a02bc252", size = 42425, upload-time = "2025-06-09T22:54:55.642Z" }, + { url = "https://files.pythonhosted.org/packages/8c/96/ef98f91bbb42b79e9bb82bdd348b255eb9d65f14dbbe3b1594644c4073f7/propcache-0.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7f08f1cc28bd2eade7a8a3d2954ccc673bb02062e3e7da09bc75d843386b342f", size = 41846, upload-time = "2025-06-09T22:54:57.246Z" }, + { url = "https://files.pythonhosted.org/packages/5b/ad/3f0f9a705fb630d175146cd7b1d2bf5555c9beaed54e94132b21aac098a6/propcache-0.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1a342c834734edb4be5ecb1e9fb48cb64b1e2320fccbd8c54bf8da8f2a84c33", size = 208871, upload-time = "2025-06-09T22:54:58.975Z" }, + { url = "https://files.pythonhosted.org/packages/3a/38/2085cda93d2c8b6ec3e92af2c89489a36a5886b712a34ab25de9fbca7992/propcache-0.3.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a544caaae1ac73f1fecfae70ded3e93728831affebd017d53449e3ac052ac1e", size = 215720, upload-time = "2025-06-09T22:55:00.471Z" }, + { url = "https://files.pythonhosted.org/packages/61/c1/d72ea2dc83ac7f2c8e182786ab0fc2c7bd123a1ff9b7975bee671866fe5f/propcache-0.3.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:310d11aa44635298397db47a3ebce7db99a4cc4b9bbdfcf6c98a60c8d5261cf1", size = 215203, upload-time = "2025-06-09T22:55:01.834Z" }, + { url = "https://files.pythonhosted.org/packages/af/81/b324c44ae60c56ef12007105f1460d5c304b0626ab0cc6b07c8f2a9aa0b8/propcache-0.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c1396592321ac83157ac03a2023aa6cc4a3cc3cfdecb71090054c09e5a7cce3", size = 206365, upload-time = "2025-06-09T22:55:03.199Z" }, + { url = "https://files.pythonhosted.org/packages/09/73/88549128bb89e66d2aff242488f62869014ae092db63ccea53c1cc75a81d/propcache-0.3.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cabf5b5902272565e78197edb682017d21cf3b550ba0460ee473753f28d23c1", size = 196016, upload-time = "2025-06-09T22:55:04.518Z" }, + { url = "https://files.pythonhosted.org/packages/b9/3f/3bdd14e737d145114a5eb83cb172903afba7242f67c5877f9909a20d948d/propcache-0.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0a2f2235ac46a7aa25bdeb03a9e7060f6ecbd213b1f9101c43b3090ffb971ef6", size = 205596, upload-time = "2025-06-09T22:55:05.942Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ca/2f4aa819c357d3107c3763d7ef42c03980f9ed5c48c82e01e25945d437c1/propcache-0.3.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:92b69e12e34869a6970fd2f3da91669899994b47c98f5d430b781c26f1d9f387", size = 200977, upload-time = "2025-06-09T22:55:07.792Z" }, + { url = "https://files.pythonhosted.org/packages/cd/4a/e65276c7477533c59085251ae88505caf6831c0e85ff8b2e31ebcbb949b1/propcache-0.3.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:54e02207c79968ebbdffc169591009f4474dde3b4679e16634d34c9363ff56b4", size = 197220, upload-time = "2025-06-09T22:55:09.173Z" }, + { url = "https://files.pythonhosted.org/packages/7c/54/fc7152e517cf5578278b242396ce4d4b36795423988ef39bb8cd5bf274c8/propcache-0.3.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4adfb44cb588001f68c5466579d3f1157ca07f7504fc91ec87862e2b8e556b88", size = 210642, upload-time = "2025-06-09T22:55:10.62Z" }, + { url = "https://files.pythonhosted.org/packages/b9/80/abeb4a896d2767bf5f1ea7b92eb7be6a5330645bd7fb844049c0e4045d9d/propcache-0.3.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fd3e6019dc1261cd0291ee8919dd91fbab7b169bb76aeef6c716833a3f65d206", size = 212789, upload-time = "2025-06-09T22:55:12.029Z" }, + { url = "https://files.pythonhosted.org/packages/b3/db/ea12a49aa7b2b6d68a5da8293dcf50068d48d088100ac016ad92a6a780e6/propcache-0.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4c181cad81158d71c41a2bce88edce078458e2dd5ffee7eddd6b05da85079f43", size = 205880, upload-time = "2025-06-09T22:55:13.45Z" }, + { url = "https://files.pythonhosted.org/packages/d1/e5/9076a0bbbfb65d1198007059c65639dfd56266cf8e477a9707e4b1999ff4/propcache-0.3.2-cp313-cp313-win32.whl", hash = "sha256:8a08154613f2249519e549de2330cf8e2071c2887309a7b07fb56098f5170a02", size = 37220, upload-time = "2025-06-09T22:55:15.284Z" }, + { url = "https://files.pythonhosted.org/packages/d3/f5/b369e026b09a26cd77aa88d8fffd69141d2ae00a2abaaf5380d2603f4b7f/propcache-0.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:e41671f1594fc4ab0a6dec1351864713cb3a279910ae8b58f884a88a0a632c05", size = 40678, upload-time = "2025-06-09T22:55:16.445Z" }, + { url = "https://files.pythonhosted.org/packages/a4/3a/6ece377b55544941a08d03581c7bc400a3c8cd3c2865900a68d5de79e21f/propcache-0.3.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:9a3cf035bbaf035f109987d9d55dc90e4b0e36e04bbbb95af3055ef17194057b", size = 76560, upload-time = "2025-06-09T22:55:17.598Z" }, + { url = "https://files.pythonhosted.org/packages/0c/da/64a2bb16418740fa634b0e9c3d29edff1db07f56d3546ca2d86ddf0305e1/propcache-0.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:156c03d07dc1323d8dacaa221fbe028c5c70d16709cdd63502778e6c3ccca1b0", size = 44676, upload-time = "2025-06-09T22:55:18.922Z" }, + { url = "https://files.pythonhosted.org/packages/36/7b/f025e06ea51cb72c52fb87e9b395cced02786610b60a3ed51da8af017170/propcache-0.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74413c0ba02ba86f55cf60d18daab219f7e531620c15f1e23d95563f505efe7e", size = 44701, upload-time = "2025-06-09T22:55:20.106Z" }, + { url = "https://files.pythonhosted.org/packages/a4/00/faa1b1b7c3b74fc277f8642f32a4c72ba1d7b2de36d7cdfb676db7f4303e/propcache-0.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f066b437bb3fa39c58ff97ab2ca351db465157d68ed0440abecb21715eb24b28", size = 276934, upload-time = "2025-06-09T22:55:21.5Z" }, + { url = "https://files.pythonhosted.org/packages/74/ab/935beb6f1756e0476a4d5938ff44bf0d13a055fed880caf93859b4f1baf4/propcache-0.3.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1304b085c83067914721e7e9d9917d41ad87696bf70f0bc7dee450e9c71ad0a", size = 278316, upload-time = "2025-06-09T22:55:22.918Z" }, + { url = "https://files.pythonhosted.org/packages/f8/9d/994a5c1ce4389610838d1caec74bdf0e98b306c70314d46dbe4fcf21a3e2/propcache-0.3.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab50cef01b372763a13333b4e54021bdcb291fc9a8e2ccb9c2df98be51bcde6c", size = 282619, upload-time = "2025-06-09T22:55:24.651Z" }, + { url = "https://files.pythonhosted.org/packages/2b/00/a10afce3d1ed0287cef2e09506d3be9822513f2c1e96457ee369adb9a6cd/propcache-0.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fad3b2a085ec259ad2c2842666b2a0a49dea8463579c606426128925af1ed725", size = 265896, upload-time = "2025-06-09T22:55:26.049Z" }, + { url = "https://files.pythonhosted.org/packages/2e/a8/2aa6716ffa566ca57c749edb909ad27884680887d68517e4be41b02299f3/propcache-0.3.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:261fa020c1c14deafd54c76b014956e2f86991af198c51139faf41c4d5e83892", size = 252111, upload-time = "2025-06-09T22:55:27.381Z" }, + { url = "https://files.pythonhosted.org/packages/36/4f/345ca9183b85ac29c8694b0941f7484bf419c7f0fea2d1e386b4f7893eed/propcache-0.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:46d7f8aa79c927e5f987ee3a80205c987717d3659f035c85cf0c3680526bdb44", size = 268334, upload-time = "2025-06-09T22:55:28.747Z" }, + { url = "https://files.pythonhosted.org/packages/3e/ca/fcd54f78b59e3f97b3b9715501e3147f5340167733d27db423aa321e7148/propcache-0.3.2-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:6d8f3f0eebf73e3c0ff0e7853f68be638b4043c65a70517bb575eff54edd8dbe", size = 255026, upload-time = "2025-06-09T22:55:30.184Z" }, + { url = "https://files.pythonhosted.org/packages/8b/95/8e6a6bbbd78ac89c30c225210a5c687790e532ba4088afb8c0445b77ef37/propcache-0.3.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:03c89c1b14a5452cf15403e291c0ccd7751d5b9736ecb2c5bab977ad6c5bcd81", size = 250724, upload-time = "2025-06-09T22:55:31.646Z" }, + { url = "https://files.pythonhosted.org/packages/ee/b0/0dd03616142baba28e8b2d14ce5df6631b4673850a3d4f9c0f9dd714a404/propcache-0.3.2-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:0cc17efde71e12bbaad086d679ce575268d70bc123a5a71ea7ad76f70ba30bba", size = 268868, upload-time = "2025-06-09T22:55:33.209Z" }, + { url = "https://files.pythonhosted.org/packages/c5/98/2c12407a7e4fbacd94ddd32f3b1e3d5231e77c30ef7162b12a60e2dd5ce3/propcache-0.3.2-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:acdf05d00696bc0447e278bb53cb04ca72354e562cf88ea6f9107df8e7fd9770", size = 271322, upload-time = "2025-06-09T22:55:35.065Z" }, + { url = "https://files.pythonhosted.org/packages/35/91/9cb56efbb428b006bb85db28591e40b7736847b8331d43fe335acf95f6c8/propcache-0.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4445542398bd0b5d32df908031cb1b30d43ac848e20470a878b770ec2dcc6330", size = 265778, upload-time = "2025-06-09T22:55:36.45Z" }, + { url = "https://files.pythonhosted.org/packages/9a/4c/b0fe775a2bdd01e176b14b574be679d84fc83958335790f7c9a686c1f468/propcache-0.3.2-cp313-cp313t-win32.whl", hash = "sha256:f86e5d7cd03afb3a1db8e9f9f6eff15794e79e791350ac48a8c924e6f439f394", size = 41175, upload-time = "2025-06-09T22:55:38.436Z" }, + { url = "https://files.pythonhosted.org/packages/a4/ff/47f08595e3d9b5e149c150f88d9714574f1a7cbd89fe2817158a952674bf/propcache-0.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:9704bedf6e7cbe3c65eca4379a9b53ee6a83749f047808cbb5044d40d7d72198", size = 44857, upload-time = "2025-06-09T22:55:39.687Z" }, + { url = "https://files.pythonhosted.org/packages/cc/35/cc0aaecf278bb4575b8555f2b137de5ab821595ddae9da9d3cd1da4072c7/propcache-0.3.2-py3-none-any.whl", hash = "sha256:98f1ec44fb675f5052cccc8e609c46ed23a35a1cfd18545ad4e29002d858a43f", size = 12663, upload-time = "2025-06-09T22:56:04.484Z" }, ] [[package]] name = "pycryptodome" version = "3.23.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8e/a6/8452177684d5e906854776276ddd34eca30d1b1e15aa1ee9cefc289a33f5/pycryptodome-3.23.0.tar.gz", hash = "sha256:447700a657182d60338bab09fdb27518f8856aecd80ae4c6bdddb67ff5da44ef", size = 4921276 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/5d/bdb09489b63cd34a976cc9e2a8d938114f7a53a74d3dd4f125ffa49dce82/pycryptodome-3.23.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:0011f7f00cdb74879142011f95133274741778abba114ceca229adbf8e62c3e4", size = 2495152 }, - { url = "https://files.pythonhosted.org/packages/a7/ce/7840250ed4cc0039c433cd41715536f926d6e86ce84e904068eb3244b6a6/pycryptodome-3.23.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:90460fc9e088ce095f9ee8356722d4f10f86e5be06e2354230a9880b9c549aae", size = 1639348 }, - { url = "https://files.pythonhosted.org/packages/ee/f0/991da24c55c1f688d6a3b5a11940567353f74590734ee4a64294834ae472/pycryptodome-3.23.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4764e64b269fc83b00f682c47443c2e6e85b18273712b98aa43bcb77f8570477", size = 2184033 }, - { url = "https://files.pythonhosted.org/packages/54/16/0e11882deddf00f68b68dd4e8e442ddc30641f31afeb2bc25588124ac8de/pycryptodome-3.23.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb8f24adb74984aa0e5d07a2368ad95276cf38051fe2dc6605cbcf482e04f2a7", size = 2270142 }, - { url = "https://files.pythonhosted.org/packages/d5/fc/4347fea23a3f95ffb931f383ff28b3f7b1fe868739182cb76718c0da86a1/pycryptodome-3.23.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d97618c9c6684a97ef7637ba43bdf6663a2e2e77efe0f863cce97a76af396446", size = 2309384 }, - { url = "https://files.pythonhosted.org/packages/6e/d9/c5261780b69ce66d8cfab25d2797bd6e82ba0241804694cd48be41add5eb/pycryptodome-3.23.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9a53a4fe5cb075075d515797d6ce2f56772ea7e6a1e5e4b96cf78a14bac3d265", size = 2183237 }, - { url = "https://files.pythonhosted.org/packages/5a/6f/3af2ffedd5cfa08c631f89452c6648c4d779e7772dfc388c77c920ca6bbf/pycryptodome-3.23.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:763d1d74f56f031788e5d307029caef067febf890cd1f8bf61183ae142f1a77b", size = 2343898 }, - { url = "https://files.pythonhosted.org/packages/9a/dc/9060d807039ee5de6e2f260f72f3d70ac213993a804f5e67e0a73a56dd2f/pycryptodome-3.23.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:954af0e2bd7cea83ce72243b14e4fb518b18f0c1649b576d114973e2073b273d", size = 2269197 }, - { url = "https://files.pythonhosted.org/packages/f9/34/e6c8ca177cb29dcc4967fef73f5de445912f93bd0343c9c33c8e5bf8cde8/pycryptodome-3.23.0-cp313-cp313t-win32.whl", hash = "sha256:257bb3572c63ad8ba40b89f6fc9d63a2a628e9f9708d31ee26560925ebe0210a", size = 1768600 }, - { url = "https://files.pythonhosted.org/packages/e4/1d/89756b8d7ff623ad0160f4539da571d1f594d21ee6d68be130a6eccb39a4/pycryptodome-3.23.0-cp313-cp313t-win_amd64.whl", hash = "sha256:6501790c5b62a29fcb227bd6b62012181d886a767ce9ed03b303d1f22eb5c625", size = 1799740 }, - { url = "https://files.pythonhosted.org/packages/5d/61/35a64f0feaea9fd07f0d91209e7be91726eb48c0f1bfc6720647194071e4/pycryptodome-3.23.0-cp313-cp313t-win_arm64.whl", hash = "sha256:9a77627a330ab23ca43b48b130e202582e91cc69619947840ea4d2d1be21eb39", size = 1703685 }, - { url = "https://files.pythonhosted.org/packages/db/6c/a1f71542c969912bb0e106f64f60a56cc1f0fabecf9396f45accbe63fa68/pycryptodome-3.23.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:187058ab80b3281b1de11c2e6842a357a1f71b42cb1e15bce373f3d238135c27", size = 2495627 }, - { url = "https://files.pythonhosted.org/packages/6e/4e/a066527e079fc5002390c8acdd3aca431e6ea0a50ffd7201551175b47323/pycryptodome-3.23.0-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:cfb5cd445280c5b0a4e6187a7ce8de5a07b5f3f897f235caa11f1f435f182843", size = 1640362 }, - { url = "https://files.pythonhosted.org/packages/50/52/adaf4c8c100a8c49d2bd058e5b551f73dfd8cb89eb4911e25a0c469b6b4e/pycryptodome-3.23.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67bd81fcbe34f43ad9422ee8fd4843c8e7198dd88dd3d40e6de42ee65fbe1490", size = 2182625 }, - { url = "https://files.pythonhosted.org/packages/5f/e9/a09476d436d0ff1402ac3867d933c61805ec2326c6ea557aeeac3825604e/pycryptodome-3.23.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8987bd3307a39bc03df5c8e0e3d8be0c4c3518b7f044b0f4c15d1aa78f52575", size = 2268954 }, - { url = "https://files.pythonhosted.org/packages/f9/c5/ffe6474e0c551d54cab931918127c46d70cab8f114e0c2b5a3c071c2f484/pycryptodome-3.23.0-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa0698f65e5b570426fc31b8162ed4603b0c2841cbb9088e2b01641e3065915b", size = 2308534 }, - { url = "https://files.pythonhosted.org/packages/18/28/e199677fc15ecf43010f2463fde4c1a53015d1fe95fb03bca2890836603a/pycryptodome-3.23.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:53ecbafc2b55353edcebd64bf5da94a2a2cdf5090a6915bcca6eca6cc452585a", size = 2181853 }, - { url = "https://files.pythonhosted.org/packages/ce/ea/4fdb09f2165ce1365c9eaefef36625583371ee514db58dc9b65d3a255c4c/pycryptodome-3.23.0-cp37-abi3-musllinux_1_2_i686.whl", hash = "sha256:156df9667ad9f2ad26255926524e1c136d6664b741547deb0a86a9acf5ea631f", size = 2342465 }, - { url = "https://files.pythonhosted.org/packages/22/82/6edc3fc42fe9284aead511394bac167693fb2b0e0395b28b8bedaa07ef04/pycryptodome-3.23.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:dea827b4d55ee390dc89b2afe5927d4308a8b538ae91d9c6f7a5090f397af1aa", size = 2267414 }, - { url = "https://files.pythonhosted.org/packages/59/fe/aae679b64363eb78326c7fdc9d06ec3de18bac68be4b612fc1fe8902693c/pycryptodome-3.23.0-cp37-abi3-win32.whl", hash = "sha256:507dbead45474b62b2bbe318eb1c4c8ee641077532067fec9c1aa82c31f84886", size = 1768484 }, - { url = "https://files.pythonhosted.org/packages/54/2f/e97a1b8294db0daaa87012c24a7bb714147c7ade7656973fd6c736b484ff/pycryptodome-3.23.0-cp37-abi3-win_amd64.whl", hash = "sha256:c75b52aacc6c0c260f204cbdd834f76edc9fb0d8e0da9fbf8352ef58202564e2", size = 1799636 }, - { url = "https://files.pythonhosted.org/packages/18/3d/f9441a0d798bf2b1e645adc3265e55706aead1255ccdad3856dbdcffec14/pycryptodome-3.23.0-cp37-abi3-win_arm64.whl", hash = "sha256:11eeeb6917903876f134b56ba11abe95c0b0fd5e3330def218083c7d98bbcb3c", size = 1703675 }, - { url = "https://files.pythonhosted.org/packages/d9/12/e33935a0709c07de084d7d58d330ec3f4daf7910a18e77937affdb728452/pycryptodome-3.23.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ddb95b49df036ddd264a0ad246d1be5b672000f12d6961ea2c267083a5e19379", size = 1623886 }, - { url = "https://files.pythonhosted.org/packages/22/0b/aa8f9419f25870889bebf0b26b223c6986652bdf071f000623df11212c90/pycryptodome-3.23.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e95564beb8782abfd9e431c974e14563a794a4944c29d6d3b7b5ea042110b4", size = 1672151 }, - { url = "https://files.pythonhosted.org/packages/d4/5e/63f5cbde2342b7f70a39e591dbe75d9809d6338ce0b07c10406f1a140cdc/pycryptodome-3.23.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14e15c081e912c4b0d75632acd8382dfce45b258667aa3c67caf7a4d4c13f630", size = 1664461 }, - { url = "https://files.pythonhosted.org/packages/d6/92/608fbdad566ebe499297a86aae5f2a5263818ceeecd16733006f1600403c/pycryptodome-3.23.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7fc76bf273353dc7e5207d172b83f569540fc9a28d63171061c42e361d22353", size = 1702440 }, - { url = "https://files.pythonhosted.org/packages/d1/92/2eadd1341abd2989cce2e2740b4423608ee2014acb8110438244ee97d7ff/pycryptodome-3.23.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:45c69ad715ca1a94f778215a11e66b7ff989d792a4d63b68dc586a1da1392ff5", size = 1803005 }, +sdist = { url = "https://files.pythonhosted.org/packages/8e/a6/8452177684d5e906854776276ddd34eca30d1b1e15aa1ee9cefc289a33f5/pycryptodome-3.23.0.tar.gz", hash = "sha256:447700a657182d60338bab09fdb27518f8856aecd80ae4c6bdddb67ff5da44ef", size = 4921276, upload-time = "2025-05-17T17:21:45.242Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/5d/bdb09489b63cd34a976cc9e2a8d938114f7a53a74d3dd4f125ffa49dce82/pycryptodome-3.23.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:0011f7f00cdb74879142011f95133274741778abba114ceca229adbf8e62c3e4", size = 2495152, upload-time = "2025-05-17T17:20:20.833Z" }, + { url = "https://files.pythonhosted.org/packages/a7/ce/7840250ed4cc0039c433cd41715536f926d6e86ce84e904068eb3244b6a6/pycryptodome-3.23.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:90460fc9e088ce095f9ee8356722d4f10f86e5be06e2354230a9880b9c549aae", size = 1639348, upload-time = "2025-05-17T17:20:23.171Z" }, + { url = "https://files.pythonhosted.org/packages/ee/f0/991da24c55c1f688d6a3b5a11940567353f74590734ee4a64294834ae472/pycryptodome-3.23.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4764e64b269fc83b00f682c47443c2e6e85b18273712b98aa43bcb77f8570477", size = 2184033, upload-time = "2025-05-17T17:20:25.424Z" }, + { url = "https://files.pythonhosted.org/packages/54/16/0e11882deddf00f68b68dd4e8e442ddc30641f31afeb2bc25588124ac8de/pycryptodome-3.23.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb8f24adb74984aa0e5d07a2368ad95276cf38051fe2dc6605cbcf482e04f2a7", size = 2270142, upload-time = "2025-05-17T17:20:27.808Z" }, + { url = "https://files.pythonhosted.org/packages/d5/fc/4347fea23a3f95ffb931f383ff28b3f7b1fe868739182cb76718c0da86a1/pycryptodome-3.23.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d97618c9c6684a97ef7637ba43bdf6663a2e2e77efe0f863cce97a76af396446", size = 2309384, upload-time = "2025-05-17T17:20:30.765Z" }, + { url = "https://files.pythonhosted.org/packages/6e/d9/c5261780b69ce66d8cfab25d2797bd6e82ba0241804694cd48be41add5eb/pycryptodome-3.23.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9a53a4fe5cb075075d515797d6ce2f56772ea7e6a1e5e4b96cf78a14bac3d265", size = 2183237, upload-time = "2025-05-17T17:20:33.736Z" }, + { url = "https://files.pythonhosted.org/packages/5a/6f/3af2ffedd5cfa08c631f89452c6648c4d779e7772dfc388c77c920ca6bbf/pycryptodome-3.23.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:763d1d74f56f031788e5d307029caef067febf890cd1f8bf61183ae142f1a77b", size = 2343898, upload-time = "2025-05-17T17:20:36.086Z" }, + { url = "https://files.pythonhosted.org/packages/9a/dc/9060d807039ee5de6e2f260f72f3d70ac213993a804f5e67e0a73a56dd2f/pycryptodome-3.23.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:954af0e2bd7cea83ce72243b14e4fb518b18f0c1649b576d114973e2073b273d", size = 2269197, upload-time = "2025-05-17T17:20:38.414Z" }, + { url = "https://files.pythonhosted.org/packages/f9/34/e6c8ca177cb29dcc4967fef73f5de445912f93bd0343c9c33c8e5bf8cde8/pycryptodome-3.23.0-cp313-cp313t-win32.whl", hash = "sha256:257bb3572c63ad8ba40b89f6fc9d63a2a628e9f9708d31ee26560925ebe0210a", size = 1768600, upload-time = "2025-05-17T17:20:40.688Z" }, + { url = "https://files.pythonhosted.org/packages/e4/1d/89756b8d7ff623ad0160f4539da571d1f594d21ee6d68be130a6eccb39a4/pycryptodome-3.23.0-cp313-cp313t-win_amd64.whl", hash = "sha256:6501790c5b62a29fcb227bd6b62012181d886a767ce9ed03b303d1f22eb5c625", size = 1799740, upload-time = "2025-05-17T17:20:42.413Z" }, + { url = "https://files.pythonhosted.org/packages/5d/61/35a64f0feaea9fd07f0d91209e7be91726eb48c0f1bfc6720647194071e4/pycryptodome-3.23.0-cp313-cp313t-win_arm64.whl", hash = "sha256:9a77627a330ab23ca43b48b130e202582e91cc69619947840ea4d2d1be21eb39", size = 1703685, upload-time = "2025-05-17T17:20:44.388Z" }, + { url = "https://files.pythonhosted.org/packages/db/6c/a1f71542c969912bb0e106f64f60a56cc1f0fabecf9396f45accbe63fa68/pycryptodome-3.23.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:187058ab80b3281b1de11c2e6842a357a1f71b42cb1e15bce373f3d238135c27", size = 2495627, upload-time = "2025-05-17T17:20:47.139Z" }, + { url = "https://files.pythonhosted.org/packages/6e/4e/a066527e079fc5002390c8acdd3aca431e6ea0a50ffd7201551175b47323/pycryptodome-3.23.0-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:cfb5cd445280c5b0a4e6187a7ce8de5a07b5f3f897f235caa11f1f435f182843", size = 1640362, upload-time = "2025-05-17T17:20:50.392Z" }, + { url = "https://files.pythonhosted.org/packages/50/52/adaf4c8c100a8c49d2bd058e5b551f73dfd8cb89eb4911e25a0c469b6b4e/pycryptodome-3.23.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67bd81fcbe34f43ad9422ee8fd4843c8e7198dd88dd3d40e6de42ee65fbe1490", size = 2182625, upload-time = "2025-05-17T17:20:52.866Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e9/a09476d436d0ff1402ac3867d933c61805ec2326c6ea557aeeac3825604e/pycryptodome-3.23.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8987bd3307a39bc03df5c8e0e3d8be0c4c3518b7f044b0f4c15d1aa78f52575", size = 2268954, upload-time = "2025-05-17T17:20:55.027Z" }, + { url = "https://files.pythonhosted.org/packages/f9/c5/ffe6474e0c551d54cab931918127c46d70cab8f114e0c2b5a3c071c2f484/pycryptodome-3.23.0-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa0698f65e5b570426fc31b8162ed4603b0c2841cbb9088e2b01641e3065915b", size = 2308534, upload-time = "2025-05-17T17:20:57.279Z" }, + { url = "https://files.pythonhosted.org/packages/18/28/e199677fc15ecf43010f2463fde4c1a53015d1fe95fb03bca2890836603a/pycryptodome-3.23.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:53ecbafc2b55353edcebd64bf5da94a2a2cdf5090a6915bcca6eca6cc452585a", size = 2181853, upload-time = "2025-05-17T17:20:59.322Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ea/4fdb09f2165ce1365c9eaefef36625583371ee514db58dc9b65d3a255c4c/pycryptodome-3.23.0-cp37-abi3-musllinux_1_2_i686.whl", hash = "sha256:156df9667ad9f2ad26255926524e1c136d6664b741547deb0a86a9acf5ea631f", size = 2342465, upload-time = "2025-05-17T17:21:03.83Z" }, + { url = "https://files.pythonhosted.org/packages/22/82/6edc3fc42fe9284aead511394bac167693fb2b0e0395b28b8bedaa07ef04/pycryptodome-3.23.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:dea827b4d55ee390dc89b2afe5927d4308a8b538ae91d9c6f7a5090f397af1aa", size = 2267414, upload-time = "2025-05-17T17:21:06.72Z" }, + { url = "https://files.pythonhosted.org/packages/59/fe/aae679b64363eb78326c7fdc9d06ec3de18bac68be4b612fc1fe8902693c/pycryptodome-3.23.0-cp37-abi3-win32.whl", hash = "sha256:507dbead45474b62b2bbe318eb1c4c8ee641077532067fec9c1aa82c31f84886", size = 1768484, upload-time = "2025-05-17T17:21:08.535Z" }, + { url = "https://files.pythonhosted.org/packages/54/2f/e97a1b8294db0daaa87012c24a7bb714147c7ade7656973fd6c736b484ff/pycryptodome-3.23.0-cp37-abi3-win_amd64.whl", hash = "sha256:c75b52aacc6c0c260f204cbdd834f76edc9fb0d8e0da9fbf8352ef58202564e2", size = 1799636, upload-time = "2025-05-17T17:21:10.393Z" }, + { url = "https://files.pythonhosted.org/packages/18/3d/f9441a0d798bf2b1e645adc3265e55706aead1255ccdad3856dbdcffec14/pycryptodome-3.23.0-cp37-abi3-win_arm64.whl", hash = "sha256:11eeeb6917903876f134b56ba11abe95c0b0fd5e3330def218083c7d98bbcb3c", size = 1703675, upload-time = "2025-05-17T17:21:13.146Z" }, + { url = "https://files.pythonhosted.org/packages/d9/12/e33935a0709c07de084d7d58d330ec3f4daf7910a18e77937affdb728452/pycryptodome-3.23.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ddb95b49df036ddd264a0ad246d1be5b672000f12d6961ea2c267083a5e19379", size = 1623886, upload-time = "2025-05-17T17:21:20.614Z" }, + { url = "https://files.pythonhosted.org/packages/22/0b/aa8f9419f25870889bebf0b26b223c6986652bdf071f000623df11212c90/pycryptodome-3.23.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e95564beb8782abfd9e431c974e14563a794a4944c29d6d3b7b5ea042110b4", size = 1672151, upload-time = "2025-05-17T17:21:22.666Z" }, + { url = "https://files.pythonhosted.org/packages/d4/5e/63f5cbde2342b7f70a39e591dbe75d9809d6338ce0b07c10406f1a140cdc/pycryptodome-3.23.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14e15c081e912c4b0d75632acd8382dfce45b258667aa3c67caf7a4d4c13f630", size = 1664461, upload-time = "2025-05-17T17:21:25.225Z" }, + { url = "https://files.pythonhosted.org/packages/d6/92/608fbdad566ebe499297a86aae5f2a5263818ceeecd16733006f1600403c/pycryptodome-3.23.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7fc76bf273353dc7e5207d172b83f569540fc9a28d63171061c42e361d22353", size = 1702440, upload-time = "2025-05-17T17:21:27.991Z" }, + { url = "https://files.pythonhosted.org/packages/d1/92/2eadd1341abd2989cce2e2740b4423608ee2014acb8110438244ee97d7ff/pycryptodome-3.23.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:45c69ad715ca1a94f778215a11e66b7ff989d792a4d63b68dc586a1da1392ff5", size = 1803005, upload-time = "2025-05-17T17:21:31.37Z" }, ] [[package]] @@ -1216,9 +1216,9 @@ dependencies = [ { name = "pydantic-core" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/70/7e/fb60e6fee04d0ef8f15e4e01ff187a196fa976eb0f0ab524af4599e5754c/pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06", size = 762094 } +sdist = { url = "https://files.pythonhosted.org/packages/70/7e/fb60e6fee04d0ef8f15e4e01ff187a196fa976eb0f0ab524af4599e5754c/pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06", size = 762094, upload-time = "2024-12-18T17:09:24.84Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f3/26/3e1bbe954fde7ee22a6e7d31582c642aad9e84ffe4b5fb61e63b87cd326f/pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d", size = 431765 }, + { url = "https://files.pythonhosted.org/packages/f3/26/3e1bbe954fde7ee22a6e7d31582c642aad9e84ffe4b5fb61e63b87cd326f/pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d", size = 431765, upload-time = "2024-12-18T17:09:21.953Z" }, ] [[package]] @@ -1228,72 +1228,72 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/bc/fed5f74b5d802cf9a03e83f60f18864e90e3aed7223adaca5ffb7a8d8d64/pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa", size = 1895938 }, - { url = "https://files.pythonhosted.org/packages/71/2a/185aff24ce844e39abb8dd680f4e959f0006944f4a8a0ea372d9f9ae2e53/pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c", size = 1815684 }, - { url = "https://files.pythonhosted.org/packages/c3/43/fafabd3d94d159d4f1ed62e383e264f146a17dd4d48453319fd782e7979e/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a", size = 1829169 }, - { url = "https://files.pythonhosted.org/packages/a2/d1/f2dfe1a2a637ce6800b799aa086d079998959f6f1215eb4497966efd2274/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5", size = 1867227 }, - { url = "https://files.pythonhosted.org/packages/7d/39/e06fcbcc1c785daa3160ccf6c1c38fea31f5754b756e34b65f74e99780b5/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c", size = 2037695 }, - { url = "https://files.pythonhosted.org/packages/7a/67/61291ee98e07f0650eb756d44998214231f50751ba7e13f4f325d95249ab/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7", size = 2741662 }, - { url = "https://files.pythonhosted.org/packages/32/90/3b15e31b88ca39e9e626630b4c4a1f5a0dfd09076366f4219429e6786076/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a", size = 1993370 }, - { url = "https://files.pythonhosted.org/packages/ff/83/c06d333ee3a67e2e13e07794995c1535565132940715931c1c43bfc85b11/pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236", size = 1996813 }, - { url = "https://files.pythonhosted.org/packages/7c/f7/89be1c8deb6e22618a74f0ca0d933fdcb8baa254753b26b25ad3acff8f74/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962", size = 2005287 }, - { url = "https://files.pythonhosted.org/packages/b7/7d/8eb3e23206c00ef7feee17b83a4ffa0a623eb1a9d382e56e4aa46fd15ff2/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9", size = 2128414 }, - { url = "https://files.pythonhosted.org/packages/4e/99/fe80f3ff8dd71a3ea15763878d464476e6cb0a2db95ff1c5c554133b6b83/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af", size = 2155301 }, - { url = "https://files.pythonhosted.org/packages/2b/a3/e50460b9a5789ca1451b70d4f52546fa9e2b420ba3bfa6100105c0559238/pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4", size = 1816685 }, - { url = "https://files.pythonhosted.org/packages/57/4c/a8838731cb0f2c2a39d3535376466de6049034d7b239c0202a64aaa05533/pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31", size = 1982876 }, - { url = "https://files.pythonhosted.org/packages/c2/89/f3450af9d09d44eea1f2c369f49e8f181d742f28220f88cc4dfaae91ea6e/pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc", size = 1893421 }, - { url = "https://files.pythonhosted.org/packages/9e/e3/71fe85af2021f3f386da42d291412e5baf6ce7716bd7101ea49c810eda90/pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7", size = 1814998 }, - { url = "https://files.pythonhosted.org/packages/a6/3c/724039e0d848fd69dbf5806894e26479577316c6f0f112bacaf67aa889ac/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15", size = 1826167 }, - { url = "https://files.pythonhosted.org/packages/2b/5b/1b29e8c1fb5f3199a9a57c1452004ff39f494bbe9bdbe9a81e18172e40d3/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306", size = 1865071 }, - { url = "https://files.pythonhosted.org/packages/89/6c/3985203863d76bb7d7266e36970d7e3b6385148c18a68cc8915fd8c84d57/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99", size = 2036244 }, - { url = "https://files.pythonhosted.org/packages/0e/41/f15316858a246b5d723f7d7f599f79e37493b2e84bfc789e58d88c209f8a/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459", size = 2737470 }, - { url = "https://files.pythonhosted.org/packages/a8/7c/b860618c25678bbd6d1d99dbdfdf0510ccb50790099b963ff78a124b754f/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048", size = 1992291 }, - { url = "https://files.pythonhosted.org/packages/bf/73/42c3742a391eccbeab39f15213ecda3104ae8682ba3c0c28069fbcb8c10d/pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d", size = 1994613 }, - { url = "https://files.pythonhosted.org/packages/94/7a/941e89096d1175d56f59340f3a8ebaf20762fef222c298ea96d36a6328c5/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b", size = 2002355 }, - { url = "https://files.pythonhosted.org/packages/6e/95/2359937a73d49e336a5a19848713555605d4d8d6940c3ec6c6c0ca4dcf25/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474", size = 2126661 }, - { url = "https://files.pythonhosted.org/packages/2b/4c/ca02b7bdb6012a1adef21a50625b14f43ed4d11f1fc237f9d7490aa5078c/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6", size = 2153261 }, - { url = "https://files.pythonhosted.org/packages/72/9d/a241db83f973049a1092a079272ffe2e3e82e98561ef6214ab53fe53b1c7/pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c", size = 1812361 }, - { url = "https://files.pythonhosted.org/packages/e8/ef/013f07248041b74abd48a385e2110aa3a9bbfef0fbd97d4e6d07d2f5b89a/pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc", size = 1982484 }, - { url = "https://files.pythonhosted.org/packages/10/1c/16b3a3e3398fd29dca77cea0a1d998d6bde3902fa2706985191e2313cc76/pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4", size = 1867102 }, - { url = "https://files.pythonhosted.org/packages/d6/74/51c8a5482ca447871c93e142d9d4a92ead74de6c8dc5e66733e22c9bba89/pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", size = 1893127 }, - { url = "https://files.pythonhosted.org/packages/d3/f3/c97e80721735868313c58b89d2de85fa80fe8dfeeed84dc51598b92a135e/pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", size = 1811340 }, - { url = "https://files.pythonhosted.org/packages/9e/91/840ec1375e686dbae1bd80a9e46c26a1e0083e1186abc610efa3d9a36180/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", size = 1822900 }, - { url = "https://files.pythonhosted.org/packages/f6/31/4240bc96025035500c18adc149aa6ffdf1a0062a4b525c932065ceb4d868/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", size = 1869177 }, - { url = "https://files.pythonhosted.org/packages/fa/20/02fbaadb7808be578317015c462655c317a77a7c8f0ef274bc016a784c54/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", size = 2038046 }, - { url = "https://files.pythonhosted.org/packages/06/86/7f306b904e6c9eccf0668248b3f272090e49c275bc488a7b88b0823444a4/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", size = 2685386 }, - { url = "https://files.pythonhosted.org/packages/8d/f0/49129b27c43396581a635d8710dae54a791b17dfc50c70164866bbf865e3/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", size = 1997060 }, - { url = "https://files.pythonhosted.org/packages/0d/0f/943b4af7cd416c477fd40b187036c4f89b416a33d3cc0ab7b82708a667aa/pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", size = 2004870 }, - { url = "https://files.pythonhosted.org/packages/35/40/aea70b5b1a63911c53a4c8117c0a828d6790483f858041f47bab0b779f44/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", size = 1999822 }, - { url = "https://files.pythonhosted.org/packages/f2/b3/807b94fd337d58effc5498fd1a7a4d9d59af4133e83e32ae39a96fddec9d/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", size = 2130364 }, - { url = "https://files.pythonhosted.org/packages/fc/df/791c827cd4ee6efd59248dca9369fb35e80a9484462c33c6649a8d02b565/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", size = 2158303 }, - { url = "https://files.pythonhosted.org/packages/9b/67/4e197c300976af185b7cef4c02203e175fb127e414125916bf1128b639a9/pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", size = 1834064 }, - { url = "https://files.pythonhosted.org/packages/1f/ea/cd7209a889163b8dcca139fe32b9687dd05249161a3edda62860430457a5/pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", size = 1989046 }, - { url = "https://files.pythonhosted.org/packages/bc/49/c54baab2f4658c26ac633d798dab66b4c3a9bbf47cff5284e9c182f4137a/pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", size = 1885092 }, - { url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709 }, - { url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273 }, - { url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027 }, - { url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888 }, - { url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738 }, - { url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138 }, - { url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025 }, - { url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633 }, - { url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404 }, - { url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130 }, - { url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946 }, - { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387 }, - { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453 }, - { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186 }, - { url = "https://files.pythonhosted.org/packages/46/72/af70981a341500419e67d5cb45abe552a7c74b66326ac8877588488da1ac/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e", size = 1891159 }, - { url = "https://files.pythonhosted.org/packages/ad/3d/c5913cccdef93e0a6a95c2d057d2c2cba347815c845cda79ddd3c0f5e17d/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8", size = 1768331 }, - { url = "https://files.pythonhosted.org/packages/f6/f0/a3ae8fbee269e4934f14e2e0e00928f9346c5943174f2811193113e58252/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3", size = 1822467 }, - { url = "https://files.pythonhosted.org/packages/d7/7a/7bbf241a04e9f9ea24cd5874354a83526d639b02674648af3f350554276c/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f", size = 1979797 }, - { url = "https://files.pythonhosted.org/packages/4f/5f/4784c6107731f89e0005a92ecb8a2efeafdb55eb992b8e9d0a2be5199335/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133", size = 1987839 }, - { url = "https://files.pythonhosted.org/packages/6d/a7/61246562b651dff00de86a5f01b6e4befb518df314c54dec187a78d81c84/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc", size = 1998861 }, - { url = "https://files.pythonhosted.org/packages/86/aa/837821ecf0c022bbb74ca132e117c358321e72e7f9702d1b6a03758545e2/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50", size = 2116582 }, - { url = "https://files.pythonhosted.org/packages/81/b0/5e74656e95623cbaa0a6278d16cf15e10a51f6002e3ec126541e95c29ea3/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9", size = 2151985 }, - { url = "https://files.pythonhosted.org/packages/63/37/3e32eeb2a451fddaa3898e2163746b0cffbbdbb4740d38372db0490d67f3/pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151", size = 2004715 }, +sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443, upload-time = "2024-12-18T11:31:54.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/bc/fed5f74b5d802cf9a03e83f60f18864e90e3aed7223adaca5ffb7a8d8d64/pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa", size = 1895938, upload-time = "2024-12-18T11:27:14.406Z" }, + { url = "https://files.pythonhosted.org/packages/71/2a/185aff24ce844e39abb8dd680f4e959f0006944f4a8a0ea372d9f9ae2e53/pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c", size = 1815684, upload-time = "2024-12-18T11:27:16.489Z" }, + { url = "https://files.pythonhosted.org/packages/c3/43/fafabd3d94d159d4f1ed62e383e264f146a17dd4d48453319fd782e7979e/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a", size = 1829169, upload-time = "2024-12-18T11:27:22.16Z" }, + { url = "https://files.pythonhosted.org/packages/a2/d1/f2dfe1a2a637ce6800b799aa086d079998959f6f1215eb4497966efd2274/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5", size = 1867227, upload-time = "2024-12-18T11:27:25.097Z" }, + { url = "https://files.pythonhosted.org/packages/7d/39/e06fcbcc1c785daa3160ccf6c1c38fea31f5754b756e34b65f74e99780b5/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c", size = 2037695, upload-time = "2024-12-18T11:27:28.656Z" }, + { url = "https://files.pythonhosted.org/packages/7a/67/61291ee98e07f0650eb756d44998214231f50751ba7e13f4f325d95249ab/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7", size = 2741662, upload-time = "2024-12-18T11:27:30.798Z" }, + { url = "https://files.pythonhosted.org/packages/32/90/3b15e31b88ca39e9e626630b4c4a1f5a0dfd09076366f4219429e6786076/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a", size = 1993370, upload-time = "2024-12-18T11:27:33.692Z" }, + { url = "https://files.pythonhosted.org/packages/ff/83/c06d333ee3a67e2e13e07794995c1535565132940715931c1c43bfc85b11/pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236", size = 1996813, upload-time = "2024-12-18T11:27:37.111Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f7/89be1c8deb6e22618a74f0ca0d933fdcb8baa254753b26b25ad3acff8f74/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962", size = 2005287, upload-time = "2024-12-18T11:27:40.566Z" }, + { url = "https://files.pythonhosted.org/packages/b7/7d/8eb3e23206c00ef7feee17b83a4ffa0a623eb1a9d382e56e4aa46fd15ff2/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9", size = 2128414, upload-time = "2024-12-18T11:27:43.757Z" }, + { url = "https://files.pythonhosted.org/packages/4e/99/fe80f3ff8dd71a3ea15763878d464476e6cb0a2db95ff1c5c554133b6b83/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af", size = 2155301, upload-time = "2024-12-18T11:27:47.36Z" }, + { url = "https://files.pythonhosted.org/packages/2b/a3/e50460b9a5789ca1451b70d4f52546fa9e2b420ba3bfa6100105c0559238/pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4", size = 1816685, upload-time = "2024-12-18T11:27:50.508Z" }, + { url = "https://files.pythonhosted.org/packages/57/4c/a8838731cb0f2c2a39d3535376466de6049034d7b239c0202a64aaa05533/pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31", size = 1982876, upload-time = "2024-12-18T11:27:53.54Z" }, + { url = "https://files.pythonhosted.org/packages/c2/89/f3450af9d09d44eea1f2c369f49e8f181d742f28220f88cc4dfaae91ea6e/pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc", size = 1893421, upload-time = "2024-12-18T11:27:55.409Z" }, + { url = "https://files.pythonhosted.org/packages/9e/e3/71fe85af2021f3f386da42d291412e5baf6ce7716bd7101ea49c810eda90/pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7", size = 1814998, upload-time = "2024-12-18T11:27:57.252Z" }, + { url = "https://files.pythonhosted.org/packages/a6/3c/724039e0d848fd69dbf5806894e26479577316c6f0f112bacaf67aa889ac/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15", size = 1826167, upload-time = "2024-12-18T11:27:59.146Z" }, + { url = "https://files.pythonhosted.org/packages/2b/5b/1b29e8c1fb5f3199a9a57c1452004ff39f494bbe9bdbe9a81e18172e40d3/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306", size = 1865071, upload-time = "2024-12-18T11:28:02.625Z" }, + { url = "https://files.pythonhosted.org/packages/89/6c/3985203863d76bb7d7266e36970d7e3b6385148c18a68cc8915fd8c84d57/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99", size = 2036244, upload-time = "2024-12-18T11:28:04.442Z" }, + { url = "https://files.pythonhosted.org/packages/0e/41/f15316858a246b5d723f7d7f599f79e37493b2e84bfc789e58d88c209f8a/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459", size = 2737470, upload-time = "2024-12-18T11:28:07.679Z" }, + { url = "https://files.pythonhosted.org/packages/a8/7c/b860618c25678bbd6d1d99dbdfdf0510ccb50790099b963ff78a124b754f/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048", size = 1992291, upload-time = "2024-12-18T11:28:10.297Z" }, + { url = "https://files.pythonhosted.org/packages/bf/73/42c3742a391eccbeab39f15213ecda3104ae8682ba3c0c28069fbcb8c10d/pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d", size = 1994613, upload-time = "2024-12-18T11:28:13.362Z" }, + { url = "https://files.pythonhosted.org/packages/94/7a/941e89096d1175d56f59340f3a8ebaf20762fef222c298ea96d36a6328c5/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b", size = 2002355, upload-time = "2024-12-18T11:28:16.587Z" }, + { url = "https://files.pythonhosted.org/packages/6e/95/2359937a73d49e336a5a19848713555605d4d8d6940c3ec6c6c0ca4dcf25/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474", size = 2126661, upload-time = "2024-12-18T11:28:18.407Z" }, + { url = "https://files.pythonhosted.org/packages/2b/4c/ca02b7bdb6012a1adef21a50625b14f43ed4d11f1fc237f9d7490aa5078c/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6", size = 2153261, upload-time = "2024-12-18T11:28:21.471Z" }, + { url = "https://files.pythonhosted.org/packages/72/9d/a241db83f973049a1092a079272ffe2e3e82e98561ef6214ab53fe53b1c7/pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c", size = 1812361, upload-time = "2024-12-18T11:28:23.53Z" }, + { url = "https://files.pythonhosted.org/packages/e8/ef/013f07248041b74abd48a385e2110aa3a9bbfef0fbd97d4e6d07d2f5b89a/pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc", size = 1982484, upload-time = "2024-12-18T11:28:25.391Z" }, + { url = "https://files.pythonhosted.org/packages/10/1c/16b3a3e3398fd29dca77cea0a1d998d6bde3902fa2706985191e2313cc76/pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4", size = 1867102, upload-time = "2024-12-18T11:28:28.593Z" }, + { url = "https://files.pythonhosted.org/packages/d6/74/51c8a5482ca447871c93e142d9d4a92ead74de6c8dc5e66733e22c9bba89/pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", size = 1893127, upload-time = "2024-12-18T11:28:30.346Z" }, + { url = "https://files.pythonhosted.org/packages/d3/f3/c97e80721735868313c58b89d2de85fa80fe8dfeeed84dc51598b92a135e/pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", size = 1811340, upload-time = "2024-12-18T11:28:32.521Z" }, + { url = "https://files.pythonhosted.org/packages/9e/91/840ec1375e686dbae1bd80a9e46c26a1e0083e1186abc610efa3d9a36180/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", size = 1822900, upload-time = "2024-12-18T11:28:34.507Z" }, + { url = "https://files.pythonhosted.org/packages/f6/31/4240bc96025035500c18adc149aa6ffdf1a0062a4b525c932065ceb4d868/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", size = 1869177, upload-time = "2024-12-18T11:28:36.488Z" }, + { url = "https://files.pythonhosted.org/packages/fa/20/02fbaadb7808be578317015c462655c317a77a7c8f0ef274bc016a784c54/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", size = 2038046, upload-time = "2024-12-18T11:28:39.409Z" }, + { url = "https://files.pythonhosted.org/packages/06/86/7f306b904e6c9eccf0668248b3f272090e49c275bc488a7b88b0823444a4/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", size = 2685386, upload-time = "2024-12-18T11:28:41.221Z" }, + { url = "https://files.pythonhosted.org/packages/8d/f0/49129b27c43396581a635d8710dae54a791b17dfc50c70164866bbf865e3/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", size = 1997060, upload-time = "2024-12-18T11:28:44.709Z" }, + { url = "https://files.pythonhosted.org/packages/0d/0f/943b4af7cd416c477fd40b187036c4f89b416a33d3cc0ab7b82708a667aa/pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", size = 2004870, upload-time = "2024-12-18T11:28:46.839Z" }, + { url = "https://files.pythonhosted.org/packages/35/40/aea70b5b1a63911c53a4c8117c0a828d6790483f858041f47bab0b779f44/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", size = 1999822, upload-time = "2024-12-18T11:28:48.896Z" }, + { url = "https://files.pythonhosted.org/packages/f2/b3/807b94fd337d58effc5498fd1a7a4d9d59af4133e83e32ae39a96fddec9d/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", size = 2130364, upload-time = "2024-12-18T11:28:50.755Z" }, + { url = "https://files.pythonhosted.org/packages/fc/df/791c827cd4ee6efd59248dca9369fb35e80a9484462c33c6649a8d02b565/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", size = 2158303, upload-time = "2024-12-18T11:28:54.122Z" }, + { url = "https://files.pythonhosted.org/packages/9b/67/4e197c300976af185b7cef4c02203e175fb127e414125916bf1128b639a9/pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", size = 1834064, upload-time = "2024-12-18T11:28:56.074Z" }, + { url = "https://files.pythonhosted.org/packages/1f/ea/cd7209a889163b8dcca139fe32b9687dd05249161a3edda62860430457a5/pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", size = 1989046, upload-time = "2024-12-18T11:28:58.107Z" }, + { url = "https://files.pythonhosted.org/packages/bc/49/c54baab2f4658c26ac633d798dab66b4c3a9bbf47cff5284e9c182f4137a/pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", size = 1885092, upload-time = "2024-12-18T11:29:01.335Z" }, + { url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709, upload-time = "2024-12-18T11:29:03.193Z" }, + { url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273, upload-time = "2024-12-18T11:29:05.306Z" }, + { url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027, upload-time = "2024-12-18T11:29:07.294Z" }, + { url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888, upload-time = "2024-12-18T11:29:09.249Z" }, + { url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738, upload-time = "2024-12-18T11:29:11.23Z" }, + { url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138, upload-time = "2024-12-18T11:29:16.396Z" }, + { url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025, upload-time = "2024-12-18T11:29:20.25Z" }, + { url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633, upload-time = "2024-12-18T11:29:23.877Z" }, + { url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404, upload-time = "2024-12-18T11:29:25.872Z" }, + { url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130, upload-time = "2024-12-18T11:29:29.252Z" }, + { url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946, upload-time = "2024-12-18T11:29:31.338Z" }, + { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387, upload-time = "2024-12-18T11:29:33.481Z" }, + { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453, upload-time = "2024-12-18T11:29:35.533Z" }, + { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186, upload-time = "2024-12-18T11:29:37.649Z" }, + { url = "https://files.pythonhosted.org/packages/46/72/af70981a341500419e67d5cb45abe552a7c74b66326ac8877588488da1ac/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e", size = 1891159, upload-time = "2024-12-18T11:30:54.382Z" }, + { url = "https://files.pythonhosted.org/packages/ad/3d/c5913cccdef93e0a6a95c2d057d2c2cba347815c845cda79ddd3c0f5e17d/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8", size = 1768331, upload-time = "2024-12-18T11:30:58.178Z" }, + { url = "https://files.pythonhosted.org/packages/f6/f0/a3ae8fbee269e4934f14e2e0e00928f9346c5943174f2811193113e58252/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3", size = 1822467, upload-time = "2024-12-18T11:31:00.6Z" }, + { url = "https://files.pythonhosted.org/packages/d7/7a/7bbf241a04e9f9ea24cd5874354a83526d639b02674648af3f350554276c/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f", size = 1979797, upload-time = "2024-12-18T11:31:07.243Z" }, + { url = "https://files.pythonhosted.org/packages/4f/5f/4784c6107731f89e0005a92ecb8a2efeafdb55eb992b8e9d0a2be5199335/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133", size = 1987839, upload-time = "2024-12-18T11:31:09.775Z" }, + { url = "https://files.pythonhosted.org/packages/6d/a7/61246562b651dff00de86a5f01b6e4befb518df314c54dec187a78d81c84/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc", size = 1998861, upload-time = "2024-12-18T11:31:13.469Z" }, + { url = "https://files.pythonhosted.org/packages/86/aa/837821ecf0c022bbb74ca132e117c358321e72e7f9702d1b6a03758545e2/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50", size = 2116582, upload-time = "2024-12-18T11:31:17.423Z" }, + { url = "https://files.pythonhosted.org/packages/81/b0/5e74656e95623cbaa0a6278d16cf15e10a51f6002e3ec126541e95c29ea3/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9", size = 2151985, upload-time = "2024-12-18T11:31:19.901Z" }, + { url = "https://files.pythonhosted.org/packages/63/37/3e32eeb2a451fddaa3898e2163746b0cffbbdbb4740d38372db0490d67f3/pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151", size = 2004715, upload-time = "2024-12-18T11:31:22.821Z" }, ] [[package]] @@ -1305,18 +1305,18 @@ dependencies = [ { name = "python-dotenv" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/67/1d/42628a2c33e93f8e9acbde0d5d735fa0850f3e6a2f8cb1eb6c40b9a732ac/pydantic_settings-2.9.1.tar.gz", hash = "sha256:c509bf79d27563add44e8446233359004ed85066cd096d8b510f715e6ef5d268", size = 163234 } +sdist = { url = "https://files.pythonhosted.org/packages/67/1d/42628a2c33e93f8e9acbde0d5d735fa0850f3e6a2f8cb1eb6c40b9a732ac/pydantic_settings-2.9.1.tar.gz", hash = "sha256:c509bf79d27563add44e8446233359004ed85066cd096d8b510f715e6ef5d268", size = 163234, upload-time = "2025-04-18T16:44:48.265Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b6/5f/d6d641b490fd3ec2c4c13b4244d68deea3a1b970a97be64f34fb5504ff72/pydantic_settings-2.9.1-py3-none-any.whl", hash = "sha256:59b4f431b1defb26fe620c71a7d3968a710d719f5f4cdbbdb7926edeb770f6ef", size = 44356 }, + { url = "https://files.pythonhosted.org/packages/b6/5f/d6d641b490fd3ec2c4c13b4244d68deea3a1b970a97be64f34fb5504ff72/pydantic_settings-2.9.1-py3-none-any.whl", hash = "sha256:59b4f431b1defb26fe620c71a7d3968a710d719f5f4cdbbdb7926edeb770f6ef", size = 44356, upload-time = "2025-04-18T16:44:46.617Z" }, ] [[package]] name = "pygments" version = "2.19.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581 } +sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581, upload-time = "2025-01-06T17:26:30.443Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293 }, + { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293, upload-time = "2025-01-06T17:26:25.553Z" }, ] [[package]] @@ -1332,9 +1332,9 @@ dependencies = [ { name = "pygments" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fb/aa/405082ce2749be5398045152251ac69c0f3578c7077efc53431303af97ce/pytest-8.4.0.tar.gz", hash = "sha256:14d920b48472ea0dbf68e45b96cd1ffda4705f33307dcc86c676c1b5104838a6", size = 1515232 } +sdist = { url = "https://files.pythonhosted.org/packages/fb/aa/405082ce2749be5398045152251ac69c0f3578c7077efc53431303af97ce/pytest-8.4.0.tar.gz", hash = "sha256:14d920b48472ea0dbf68e45b96cd1ffda4705f33307dcc86c676c1b5104838a6", size = 1515232, upload-time = "2025-06-02T17:36:30.03Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/de/afa024cbe022b1b318a3d224125aa24939e99b4ff6f22e0ba639a2eaee47/pytest-8.4.0-py3-none-any.whl", hash = "sha256:f40f825768ad76c0977cbacdf1fd37c6f7a468e460ea6a0636078f8972d4517e", size = 363797 }, + { url = "https://files.pythonhosted.org/packages/2f/de/afa024cbe022b1b318a3d224125aa24939e99b4ff6f22e0ba639a2eaee47/pytest-8.4.0-py3-none-any.whl", hash = "sha256:f40f825768ad76c0977cbacdf1fd37c6f7a468e460ea6a0636078f8972d4517e", size = 363797, upload-time = "2025-06-02T17:36:27.859Z" }, ] [[package]] @@ -1344,36 +1344,36 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d0/d4/14f53324cb1a6381bef29d698987625d80052bb33932d8e7cbf9b337b17c/pytest_asyncio-1.0.0.tar.gz", hash = "sha256:d15463d13f4456e1ead2594520216b225a16f781e144f8fdf6c5bb4667c48b3f", size = 46960 } +sdist = { url = "https://files.pythonhosted.org/packages/d0/d4/14f53324cb1a6381bef29d698987625d80052bb33932d8e7cbf9b337b17c/pytest_asyncio-1.0.0.tar.gz", hash = "sha256:d15463d13f4456e1ead2594520216b225a16f781e144f8fdf6c5bb4667c48b3f", size = 46960, upload-time = "2025-05-26T04:54:40.484Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/30/05/ce271016e351fddc8399e546f6e23761967ee09c8c568bbfbecb0c150171/pytest_asyncio-1.0.0-py3-none-any.whl", hash = "sha256:4f024da9f1ef945e680dc68610b52550e36590a67fd31bb3b4943979a1f90ef3", size = 15976 }, + { url = "https://files.pythonhosted.org/packages/30/05/ce271016e351fddc8399e546f6e23761967ee09c8c568bbfbecb0c150171/pytest_asyncio-1.0.0-py3-none-any.whl", hash = "sha256:4f024da9f1ef945e680dc68610b52550e36590a67fd31bb3b4943979a1f90ef3", size = 15976, upload-time = "2025-05-26T04:54:39.035Z" }, ] [[package]] name = "python-dotenv" version = "1.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/88/2c/7bb1416c5620485aa793f2de31d3df393d3686aa8a8506d11e10e13c5baf/python_dotenv-1.1.0.tar.gz", hash = "sha256:41f90bc6f5f177fb41f53e87666db362025010eb28f60a01c9143bfa33a2b2d5", size = 39920 } +sdist = { url = "https://files.pythonhosted.org/packages/88/2c/7bb1416c5620485aa793f2de31d3df393d3686aa8a8506d11e10e13c5baf/python_dotenv-1.1.0.tar.gz", hash = "sha256:41f90bc6f5f177fb41f53e87666db362025010eb28f60a01c9143bfa33a2b2d5", size = 39920, upload-time = "2025-03-25T10:14:56.835Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/18/98a99ad95133c6a6e2005fe89faedf294a748bd5dc803008059409ac9b1e/python_dotenv-1.1.0-py3-none-any.whl", hash = "sha256:d7c01d9e2293916c18baf562d95698754b0dbbb5e74d457c45d4f6561fb9d55d", size = 20256 }, + { url = "https://files.pythonhosted.org/packages/1e/18/98a99ad95133c6a6e2005fe89faedf294a748bd5dc803008059409ac9b1e/python_dotenv-1.1.0-py3-none-any.whl", hash = "sha256:d7c01d9e2293916c18baf562d95698754b0dbbb5e74d457c45d4f6561fb9d55d", size = 20256, upload-time = "2025-03-25T10:14:55.034Z" }, ] [[package]] name = "python-multipart" version = "0.0.20" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158 } +sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158, upload-time = "2024-12-16T19:45:46.972Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546 }, + { url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546, upload-time = "2024-12-16T19:45:44.423Z" }, ] [[package]] name = "pyunormalize" version = "16.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b3/08/568036c725dac746ecb267bb749ef930fb7907454fe69fce83c8557287fb/pyunormalize-16.0.0.tar.gz", hash = "sha256:2e1dfbb4a118154ae26f70710426a52a364b926c9191f764601f5a8cb12761f7", size = 49968 } +sdist = { url = "https://files.pythonhosted.org/packages/b3/08/568036c725dac746ecb267bb749ef930fb7907454fe69fce83c8557287fb/pyunormalize-16.0.0.tar.gz", hash = "sha256:2e1dfbb4a118154ae26f70710426a52a364b926c9191f764601f5a8cb12761f7", size = 49968, upload-time = "2024-09-17T17:08:18.245Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/39/f9/9d86e56f716e0651194a5ad58be9c146fcaf1de6901ac6f3cd3affeeb74e/pyunormalize-16.0.0-py3-none-any.whl", hash = "sha256:c647d95e5d1e2ea9a2f448d1d95d8518348df24eab5c3fd32d2b5c3300a49152", size = 49173 }, + { url = "https://files.pythonhosted.org/packages/39/f9/9d86e56f716e0651194a5ad58be9c146fcaf1de6901ac6f3cd3affeeb74e/pyunormalize-16.0.0-py3-none-any.whl", hash = "sha256:c647d95e5d1e2ea9a2f448d1d95d8518348df24eab5c3fd32d2b5c3300a49152", size = 49173, upload-time = "2024-09-17T17:08:17.078Z" }, ] [[package]] @@ -1381,131 +1381,131 @@ name = "pywin32" version = "310" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/95/da/a5f38fffbba2fb99aa4aa905480ac4b8e83ca486659ac8c95bce47fb5276/pywin32-310-cp310-cp310-win32.whl", hash = "sha256:6dd97011efc8bf51d6793a82292419eba2c71cf8e7250cfac03bba284454abc1", size = 8848240 }, - { url = "https://files.pythonhosted.org/packages/aa/fe/d873a773324fa565619ba555a82c9dabd677301720f3660a731a5d07e49a/pywin32-310-cp310-cp310-win_amd64.whl", hash = "sha256:c3e78706e4229b915a0821941a84e7ef420bf2b77e08c9dae3c76fd03fd2ae3d", size = 9601854 }, - { url = "https://files.pythonhosted.org/packages/3c/84/1a8e3d7a15490d28a5d816efa229ecb4999cdc51a7c30dd8914f669093b8/pywin32-310-cp310-cp310-win_arm64.whl", hash = "sha256:33babed0cf0c92a6f94cc6cc13546ab24ee13e3e800e61ed87609ab91e4c8213", size = 8522963 }, - { url = "https://files.pythonhosted.org/packages/f7/b1/68aa2986129fb1011dabbe95f0136f44509afaf072b12b8f815905a39f33/pywin32-310-cp311-cp311-win32.whl", hash = "sha256:1e765f9564e83011a63321bb9d27ec456a0ed90d3732c4b2e312b855365ed8bd", size = 8784284 }, - { url = "https://files.pythonhosted.org/packages/b3/bd/d1592635992dd8db5bb8ace0551bc3a769de1ac8850200cfa517e72739fb/pywin32-310-cp311-cp311-win_amd64.whl", hash = "sha256:126298077a9d7c95c53823934f000599f66ec9296b09167810eb24875f32689c", size = 9520748 }, - { url = "https://files.pythonhosted.org/packages/90/b1/ac8b1ffce6603849eb45a91cf126c0fa5431f186c2e768bf56889c46f51c/pywin32-310-cp311-cp311-win_arm64.whl", hash = "sha256:19ec5fc9b1d51c4350be7bb00760ffce46e6c95eaf2f0b2f1150657b1a43c582", size = 8455941 }, - { url = "https://files.pythonhosted.org/packages/6b/ec/4fdbe47932f671d6e348474ea35ed94227fb5df56a7c30cbbb42cd396ed0/pywin32-310-cp312-cp312-win32.whl", hash = "sha256:8a75a5cc3893e83a108c05d82198880704c44bbaee4d06e442e471d3c9ea4f3d", size = 8796239 }, - { url = "https://files.pythonhosted.org/packages/e3/e5/b0627f8bb84e06991bea89ad8153a9e50ace40b2e1195d68e9dff6b03d0f/pywin32-310-cp312-cp312-win_amd64.whl", hash = "sha256:bf5c397c9a9a19a6f62f3fb821fbf36cac08f03770056711f765ec1503972060", size = 9503839 }, - { url = "https://files.pythonhosted.org/packages/1f/32/9ccf53748df72301a89713936645a664ec001abd35ecc8578beda593d37d/pywin32-310-cp312-cp312-win_arm64.whl", hash = "sha256:2349cc906eae872d0663d4d6290d13b90621eaf78964bb1578632ff20e152966", size = 8459470 }, - { url = "https://files.pythonhosted.org/packages/1c/09/9c1b978ffc4ae53999e89c19c77ba882d9fce476729f23ef55211ea1c034/pywin32-310-cp313-cp313-win32.whl", hash = "sha256:5d241a659c496ada3253cd01cfaa779b048e90ce4b2b38cd44168ad555ce74ab", size = 8794384 }, - { url = "https://files.pythonhosted.org/packages/45/3c/b4640f740ffebadd5d34df35fecba0e1cfef8fde9f3e594df91c28ad9b50/pywin32-310-cp313-cp313-win_amd64.whl", hash = "sha256:667827eb3a90208ddbdcc9e860c81bde63a135710e21e4cb3348968e4bd5249e", size = 9503039 }, - { url = "https://files.pythonhosted.org/packages/b4/f4/f785020090fb050e7fb6d34b780f2231f302609dc964672f72bfaeb59a28/pywin32-310-cp313-cp313-win_arm64.whl", hash = "sha256:e308f831de771482b7cf692a1f308f8fca701b2d8f9dde6cc440c7da17e47b33", size = 8458152 }, + { url = "https://files.pythonhosted.org/packages/95/da/a5f38fffbba2fb99aa4aa905480ac4b8e83ca486659ac8c95bce47fb5276/pywin32-310-cp310-cp310-win32.whl", hash = "sha256:6dd97011efc8bf51d6793a82292419eba2c71cf8e7250cfac03bba284454abc1", size = 8848240, upload-time = "2025-03-17T00:55:46.783Z" }, + { url = "https://files.pythonhosted.org/packages/aa/fe/d873a773324fa565619ba555a82c9dabd677301720f3660a731a5d07e49a/pywin32-310-cp310-cp310-win_amd64.whl", hash = "sha256:c3e78706e4229b915a0821941a84e7ef420bf2b77e08c9dae3c76fd03fd2ae3d", size = 9601854, upload-time = "2025-03-17T00:55:48.783Z" }, + { url = "https://files.pythonhosted.org/packages/3c/84/1a8e3d7a15490d28a5d816efa229ecb4999cdc51a7c30dd8914f669093b8/pywin32-310-cp310-cp310-win_arm64.whl", hash = "sha256:33babed0cf0c92a6f94cc6cc13546ab24ee13e3e800e61ed87609ab91e4c8213", size = 8522963, upload-time = "2025-03-17T00:55:50.969Z" }, + { url = "https://files.pythonhosted.org/packages/f7/b1/68aa2986129fb1011dabbe95f0136f44509afaf072b12b8f815905a39f33/pywin32-310-cp311-cp311-win32.whl", hash = "sha256:1e765f9564e83011a63321bb9d27ec456a0ed90d3732c4b2e312b855365ed8bd", size = 8784284, upload-time = "2025-03-17T00:55:53.124Z" }, + { url = "https://files.pythonhosted.org/packages/b3/bd/d1592635992dd8db5bb8ace0551bc3a769de1ac8850200cfa517e72739fb/pywin32-310-cp311-cp311-win_amd64.whl", hash = "sha256:126298077a9d7c95c53823934f000599f66ec9296b09167810eb24875f32689c", size = 9520748, upload-time = "2025-03-17T00:55:55.203Z" }, + { url = "https://files.pythonhosted.org/packages/90/b1/ac8b1ffce6603849eb45a91cf126c0fa5431f186c2e768bf56889c46f51c/pywin32-310-cp311-cp311-win_arm64.whl", hash = "sha256:19ec5fc9b1d51c4350be7bb00760ffce46e6c95eaf2f0b2f1150657b1a43c582", size = 8455941, upload-time = "2025-03-17T00:55:57.048Z" }, + { url = "https://files.pythonhosted.org/packages/6b/ec/4fdbe47932f671d6e348474ea35ed94227fb5df56a7c30cbbb42cd396ed0/pywin32-310-cp312-cp312-win32.whl", hash = "sha256:8a75a5cc3893e83a108c05d82198880704c44bbaee4d06e442e471d3c9ea4f3d", size = 8796239, upload-time = "2025-03-17T00:55:58.807Z" }, + { url = "https://files.pythonhosted.org/packages/e3/e5/b0627f8bb84e06991bea89ad8153a9e50ace40b2e1195d68e9dff6b03d0f/pywin32-310-cp312-cp312-win_amd64.whl", hash = "sha256:bf5c397c9a9a19a6f62f3fb821fbf36cac08f03770056711f765ec1503972060", size = 9503839, upload-time = "2025-03-17T00:56:00.8Z" }, + { url = "https://files.pythonhosted.org/packages/1f/32/9ccf53748df72301a89713936645a664ec001abd35ecc8578beda593d37d/pywin32-310-cp312-cp312-win_arm64.whl", hash = "sha256:2349cc906eae872d0663d4d6290d13b90621eaf78964bb1578632ff20e152966", size = 8459470, upload-time = "2025-03-17T00:56:02.601Z" }, + { url = "https://files.pythonhosted.org/packages/1c/09/9c1b978ffc4ae53999e89c19c77ba882d9fce476729f23ef55211ea1c034/pywin32-310-cp313-cp313-win32.whl", hash = "sha256:5d241a659c496ada3253cd01cfaa779b048e90ce4b2b38cd44168ad555ce74ab", size = 8794384, upload-time = "2025-03-17T00:56:04.383Z" }, + { url = "https://files.pythonhosted.org/packages/45/3c/b4640f740ffebadd5d34df35fecba0e1cfef8fde9f3e594df91c28ad9b50/pywin32-310-cp313-cp313-win_amd64.whl", hash = "sha256:667827eb3a90208ddbdcc9e860c81bde63a135710e21e4cb3348968e4bd5249e", size = 9503039, upload-time = "2025-03-17T00:56:06.207Z" }, + { url = "https://files.pythonhosted.org/packages/b4/f4/f785020090fb050e7fb6d34b780f2231f302609dc964672f72bfaeb59a28/pywin32-310-cp313-cp313-win_arm64.whl", hash = "sha256:e308f831de771482b7cf692a1f308f8fca701b2d8f9dde6cc440c7da17e47b33", size = 8458152, upload-time = "2025-03-17T00:56:07.819Z" }, ] [[package]] name = "pyyaml" version = "6.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199 }, - { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758 }, - { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463 }, - { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280 }, - { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239 }, - { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802 }, - { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527 }, - { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052 }, - { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774 }, - { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612 }, - { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040 }, - { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829 }, - { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167 }, - { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952 }, - { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301 }, - { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638 }, - { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850 }, - { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980 }, - { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873 }, - { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302 }, - { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154 }, - { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223 }, - { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542 }, - { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164 }, - { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 }, - { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 }, - { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 }, - { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 }, - { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 }, - { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 }, - { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 }, - { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 }, - { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 }, - { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 }, - { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, - { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199, upload-time = "2024-08-06T20:31:40.178Z" }, + { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758, upload-time = "2024-08-06T20:31:42.173Z" }, + { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463, upload-time = "2024-08-06T20:31:44.263Z" }, + { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280, upload-time = "2024-08-06T20:31:50.199Z" }, + { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239, upload-time = "2024-08-06T20:31:52.292Z" }, + { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802, upload-time = "2024-08-06T20:31:53.836Z" }, + { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527, upload-time = "2024-08-06T20:31:55.565Z" }, + { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052, upload-time = "2024-08-06T20:31:56.914Z" }, + { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774, upload-time = "2024-08-06T20:31:58.304Z" }, + { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612, upload-time = "2024-08-06T20:32:03.408Z" }, + { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040, upload-time = "2024-08-06T20:32:04.926Z" }, + { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829, upload-time = "2024-08-06T20:32:06.459Z" }, + { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167, upload-time = "2024-08-06T20:32:08.338Z" }, + { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952, upload-time = "2024-08-06T20:32:14.124Z" }, + { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301, upload-time = "2024-08-06T20:32:16.17Z" }, + { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638, upload-time = "2024-08-06T20:32:18.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850, upload-time = "2024-08-06T20:32:19.889Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980, upload-time = "2024-08-06T20:32:21.273Z" }, + { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873, upload-time = "2024-08-06T20:32:25.131Z" }, + { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302, upload-time = "2024-08-06T20:32:26.511Z" }, + { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154, upload-time = "2024-08-06T20:32:28.363Z" }, + { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223, upload-time = "2024-08-06T20:32:30.058Z" }, + { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542, upload-time = "2024-08-06T20:32:31.881Z" }, + { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164, upload-time = "2024-08-06T20:32:37.083Z" }, + { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611, upload-time = "2024-08-06T20:32:38.898Z" }, + { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591, upload-time = "2024-08-06T20:32:40.241Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338, upload-time = "2024-08-06T20:32:41.93Z" }, + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, ] [[package]] name = "regex" version = "2024.11.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8e/5f/bd69653fbfb76cf8604468d3b4ec4c403197144c7bfe0e6a5fc9e02a07cb/regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519", size = 399494 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/95/3c/4651f6b130c6842a8f3df82461a8950f923925db8b6961063e82744bddcc/regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91", size = 482674 }, - { url = "https://files.pythonhosted.org/packages/15/51/9f35d12da8434b489c7b7bffc205c474a0a9432a889457026e9bc06a297a/regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0", size = 287684 }, - { url = "https://files.pythonhosted.org/packages/bd/18/b731f5510d1b8fb63c6b6d3484bfa9a59b84cc578ac8b5172970e05ae07c/regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e", size = 284589 }, - { url = "https://files.pythonhosted.org/packages/78/a2/6dd36e16341ab95e4c6073426561b9bfdeb1a9c9b63ab1b579c2e96cb105/regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde", size = 782511 }, - { url = "https://files.pythonhosted.org/packages/1b/2b/323e72d5d2fd8de0d9baa443e1ed70363ed7e7b2fb526f5950c5cb99c364/regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e", size = 821149 }, - { url = "https://files.pythonhosted.org/packages/90/30/63373b9ea468fbef8a907fd273e5c329b8c9535fee36fc8dba5fecac475d/regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2", size = 809707 }, - { url = "https://files.pythonhosted.org/packages/f2/98/26d3830875b53071f1f0ae6d547f1d98e964dd29ad35cbf94439120bb67a/regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf", size = 781702 }, - { url = "https://files.pythonhosted.org/packages/87/55/eb2a068334274db86208ab9d5599ffa63631b9f0f67ed70ea7c82a69bbc8/regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c", size = 771976 }, - { url = "https://files.pythonhosted.org/packages/74/c0/be707bcfe98254d8f9d2cff55d216e946f4ea48ad2fd8cf1428f8c5332ba/regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86", size = 697397 }, - { url = "https://files.pythonhosted.org/packages/49/dc/bb45572ceb49e0f6509f7596e4ba7031f6819ecb26bc7610979af5a77f45/regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67", size = 768726 }, - { url = "https://files.pythonhosted.org/packages/5a/db/f43fd75dc4c0c2d96d0881967897926942e935d700863666f3c844a72ce6/regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d", size = 775098 }, - { url = "https://files.pythonhosted.org/packages/99/d7/f94154db29ab5a89d69ff893159b19ada89e76b915c1293e98603d39838c/regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2", size = 839325 }, - { url = "https://files.pythonhosted.org/packages/f7/17/3cbfab1f23356fbbf07708220ab438a7efa1e0f34195bf857433f79f1788/regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008", size = 843277 }, - { url = "https://files.pythonhosted.org/packages/7e/f2/48b393b51900456155de3ad001900f94298965e1cad1c772b87f9cfea011/regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62", size = 773197 }, - { url = "https://files.pythonhosted.org/packages/45/3f/ef9589aba93e084cd3f8471fded352826dcae8489b650d0b9b27bc5bba8a/regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e", size = 261714 }, - { url = "https://files.pythonhosted.org/packages/42/7e/5f1b92c8468290c465fd50c5318da64319133231415a8aa6ea5ab995a815/regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519", size = 274042 }, - { url = "https://files.pythonhosted.org/packages/58/58/7e4d9493a66c88a7da6d205768119f51af0f684fe7be7bac8328e217a52c/regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638", size = 482669 }, - { url = "https://files.pythonhosted.org/packages/34/4c/8f8e631fcdc2ff978609eaeef1d6994bf2f028b59d9ac67640ed051f1218/regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7", size = 287684 }, - { url = "https://files.pythonhosted.org/packages/c5/1b/f0e4d13e6adf866ce9b069e191f303a30ab1277e037037a365c3aad5cc9c/regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20", size = 284589 }, - { url = "https://files.pythonhosted.org/packages/25/4d/ab21047f446693887f25510887e6820b93f791992994f6498b0318904d4a/regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114", size = 792121 }, - { url = "https://files.pythonhosted.org/packages/45/ee/c867e15cd894985cb32b731d89576c41a4642a57850c162490ea34b78c3b/regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3", size = 831275 }, - { url = "https://files.pythonhosted.org/packages/b3/12/b0f480726cf1c60f6536fa5e1c95275a77624f3ac8fdccf79e6727499e28/regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f", size = 818257 }, - { url = "https://files.pythonhosted.org/packages/bf/ce/0d0e61429f603bac433910d99ef1a02ce45a8967ffbe3cbee48599e62d88/regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0", size = 792727 }, - { url = "https://files.pythonhosted.org/packages/e4/c1/243c83c53d4a419c1556f43777ccb552bccdf79d08fda3980e4e77dd9137/regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55", size = 780667 }, - { url = "https://files.pythonhosted.org/packages/c5/f4/75eb0dd4ce4b37f04928987f1d22547ddaf6c4bae697623c1b05da67a8aa/regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89", size = 776963 }, - { url = "https://files.pythonhosted.org/packages/16/5d/95c568574e630e141a69ff8a254c2f188b4398e813c40d49228c9bbd9875/regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d", size = 784700 }, - { url = "https://files.pythonhosted.org/packages/8e/b5/f8495c7917f15cc6fee1e7f395e324ec3e00ab3c665a7dc9d27562fd5290/regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34", size = 848592 }, - { url = "https://files.pythonhosted.org/packages/1c/80/6dd7118e8cb212c3c60b191b932dc57db93fb2e36fb9e0e92f72a5909af9/regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d", size = 852929 }, - { url = "https://files.pythonhosted.org/packages/11/9b/5a05d2040297d2d254baf95eeeb6df83554e5e1df03bc1a6687fc4ba1f66/regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45", size = 781213 }, - { url = "https://files.pythonhosted.org/packages/26/b7/b14e2440156ab39e0177506c08c18accaf2b8932e39fb092074de733d868/regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9", size = 261734 }, - { url = "https://files.pythonhosted.org/packages/80/32/763a6cc01d21fb3819227a1cc3f60fd251c13c37c27a73b8ff4315433a8e/regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60", size = 274052 }, - { url = "https://files.pythonhosted.org/packages/ba/30/9a87ce8336b172cc232a0db89a3af97929d06c11ceaa19d97d84fa90a8f8/regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a", size = 483781 }, - { url = "https://files.pythonhosted.org/packages/01/e8/00008ad4ff4be8b1844786ba6636035f7ef926db5686e4c0f98093612add/regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9", size = 288455 }, - { url = "https://files.pythonhosted.org/packages/60/85/cebcc0aff603ea0a201667b203f13ba75d9fc8668fab917ac5b2de3967bc/regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2", size = 284759 }, - { url = "https://files.pythonhosted.org/packages/94/2b/701a4b0585cb05472a4da28ee28fdfe155f3638f5e1ec92306d924e5faf0/regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4", size = 794976 }, - { url = "https://files.pythonhosted.org/packages/4b/bf/fa87e563bf5fee75db8915f7352e1887b1249126a1be4813837f5dbec965/regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577", size = 833077 }, - { url = "https://files.pythonhosted.org/packages/a1/56/7295e6bad94b047f4d0834e4779491b81216583c00c288252ef625c01d23/regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3", size = 823160 }, - { url = "https://files.pythonhosted.org/packages/fb/13/e3b075031a738c9598c51cfbc4c7879e26729c53aa9cca59211c44235314/regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e", size = 796896 }, - { url = "https://files.pythonhosted.org/packages/24/56/0b3f1b66d592be6efec23a795b37732682520b47c53da5a32c33ed7d84e3/regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe", size = 783997 }, - { url = "https://files.pythonhosted.org/packages/f9/a1/eb378dada8b91c0e4c5f08ffb56f25fcae47bf52ad18f9b2f33b83e6d498/regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e", size = 781725 }, - { url = "https://files.pythonhosted.org/packages/83/f2/033e7dec0cfd6dda93390089864732a3409246ffe8b042e9554afa9bff4e/regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29", size = 789481 }, - { url = "https://files.pythonhosted.org/packages/83/23/15d4552ea28990a74e7696780c438aadd73a20318c47e527b47a4a5a596d/regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39", size = 852896 }, - { url = "https://files.pythonhosted.org/packages/e3/39/ed4416bc90deedbfdada2568b2cb0bc1fdb98efe11f5378d9892b2a88f8f/regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51", size = 860138 }, - { url = "https://files.pythonhosted.org/packages/93/2d/dd56bb76bd8e95bbce684326302f287455b56242a4f9c61f1bc76e28360e/regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad", size = 787692 }, - { url = "https://files.pythonhosted.org/packages/0b/55/31877a249ab7a5156758246b9c59539abbeba22461b7d8adc9e8475ff73e/regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54", size = 262135 }, - { url = "https://files.pythonhosted.org/packages/38/ec/ad2d7de49a600cdb8dd78434a1aeffe28b9d6fc42eb36afab4a27ad23384/regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b", size = 273567 }, - { url = "https://files.pythonhosted.org/packages/90/73/bcb0e36614601016552fa9344544a3a2ae1809dc1401b100eab02e772e1f/regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84", size = 483525 }, - { url = "https://files.pythonhosted.org/packages/0f/3f/f1a082a46b31e25291d830b369b6b0c5576a6f7fb89d3053a354c24b8a83/regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4", size = 288324 }, - { url = "https://files.pythonhosted.org/packages/09/c9/4e68181a4a652fb3ef5099e077faf4fd2a694ea6e0f806a7737aff9e758a/regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0", size = 284617 }, - { url = "https://files.pythonhosted.org/packages/fc/fd/37868b75eaf63843165f1d2122ca6cb94bfc0271e4428cf58c0616786dce/regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0", size = 795023 }, - { url = "https://files.pythonhosted.org/packages/c4/7c/d4cd9c528502a3dedb5c13c146e7a7a539a3853dc20209c8e75d9ba9d1b2/regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7", size = 833072 }, - { url = "https://files.pythonhosted.org/packages/4f/db/46f563a08f969159c5a0f0e722260568425363bea43bb7ae370becb66a67/regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7", size = 823130 }, - { url = "https://files.pythonhosted.org/packages/db/60/1eeca2074f5b87df394fccaa432ae3fc06c9c9bfa97c5051aed70e6e00c2/regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c", size = 796857 }, - { url = "https://files.pythonhosted.org/packages/10/db/ac718a08fcee981554d2f7bb8402f1faa7e868c1345c16ab1ebec54b0d7b/regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3", size = 784006 }, - { url = "https://files.pythonhosted.org/packages/c2/41/7da3fe70216cea93144bf12da2b87367590bcf07db97604edeea55dac9ad/regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07", size = 781650 }, - { url = "https://files.pythonhosted.org/packages/a7/d5/880921ee4eec393a4752e6ab9f0fe28009435417c3102fc413f3fe81c4e5/regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e", size = 789545 }, - { url = "https://files.pythonhosted.org/packages/dc/96/53770115e507081122beca8899ab7f5ae28ae790bfcc82b5e38976df6a77/regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6", size = 853045 }, - { url = "https://files.pythonhosted.org/packages/31/d3/1372add5251cc2d44b451bd94f43b2ec78e15a6e82bff6a290ef9fd8f00a/regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4", size = 860182 }, - { url = "https://files.pythonhosted.org/packages/ed/e3/c446a64984ea9f69982ba1a69d4658d5014bc7a0ea468a07e1a1265db6e2/regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d", size = 787733 }, - { url = "https://files.pythonhosted.org/packages/2b/f1/e40c8373e3480e4f29f2692bd21b3e05f296d3afebc7e5dcf21b9756ca1c/regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff", size = 262122 }, - { url = "https://files.pythonhosted.org/packages/45/94/bc295babb3062a731f52621cdc992d123111282e291abaf23faa413443ea/regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a", size = 273545 }, +sdist = { url = "https://files.pythonhosted.org/packages/8e/5f/bd69653fbfb76cf8604468d3b4ec4c403197144c7bfe0e6a5fc9e02a07cb/regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519", size = 399494, upload-time = "2024-11-06T20:12:31.635Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/3c/4651f6b130c6842a8f3df82461a8950f923925db8b6961063e82744bddcc/regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91", size = 482674, upload-time = "2024-11-06T20:08:57.575Z" }, + { url = "https://files.pythonhosted.org/packages/15/51/9f35d12da8434b489c7b7bffc205c474a0a9432a889457026e9bc06a297a/regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0", size = 287684, upload-time = "2024-11-06T20:08:59.787Z" }, + { url = "https://files.pythonhosted.org/packages/bd/18/b731f5510d1b8fb63c6b6d3484bfa9a59b84cc578ac8b5172970e05ae07c/regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e", size = 284589, upload-time = "2024-11-06T20:09:01.896Z" }, + { url = "https://files.pythonhosted.org/packages/78/a2/6dd36e16341ab95e4c6073426561b9bfdeb1a9c9b63ab1b579c2e96cb105/regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde", size = 782511, upload-time = "2024-11-06T20:09:04.062Z" }, + { url = "https://files.pythonhosted.org/packages/1b/2b/323e72d5d2fd8de0d9baa443e1ed70363ed7e7b2fb526f5950c5cb99c364/regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e", size = 821149, upload-time = "2024-11-06T20:09:06.237Z" }, + { url = "https://files.pythonhosted.org/packages/90/30/63373b9ea468fbef8a907fd273e5c329b8c9535fee36fc8dba5fecac475d/regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2", size = 809707, upload-time = "2024-11-06T20:09:07.715Z" }, + { url = "https://files.pythonhosted.org/packages/f2/98/26d3830875b53071f1f0ae6d547f1d98e964dd29ad35cbf94439120bb67a/regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf", size = 781702, upload-time = "2024-11-06T20:09:10.101Z" }, + { url = "https://files.pythonhosted.org/packages/87/55/eb2a068334274db86208ab9d5599ffa63631b9f0f67ed70ea7c82a69bbc8/regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c", size = 771976, upload-time = "2024-11-06T20:09:11.566Z" }, + { url = "https://files.pythonhosted.org/packages/74/c0/be707bcfe98254d8f9d2cff55d216e946f4ea48ad2fd8cf1428f8c5332ba/regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86", size = 697397, upload-time = "2024-11-06T20:09:13.119Z" }, + { url = "https://files.pythonhosted.org/packages/49/dc/bb45572ceb49e0f6509f7596e4ba7031f6819ecb26bc7610979af5a77f45/regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67", size = 768726, upload-time = "2024-11-06T20:09:14.85Z" }, + { url = "https://files.pythonhosted.org/packages/5a/db/f43fd75dc4c0c2d96d0881967897926942e935d700863666f3c844a72ce6/regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d", size = 775098, upload-time = "2024-11-06T20:09:16.504Z" }, + { url = "https://files.pythonhosted.org/packages/99/d7/f94154db29ab5a89d69ff893159b19ada89e76b915c1293e98603d39838c/regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2", size = 839325, upload-time = "2024-11-06T20:09:18.698Z" }, + { url = "https://files.pythonhosted.org/packages/f7/17/3cbfab1f23356fbbf07708220ab438a7efa1e0f34195bf857433f79f1788/regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008", size = 843277, upload-time = "2024-11-06T20:09:21.725Z" }, + { url = "https://files.pythonhosted.org/packages/7e/f2/48b393b51900456155de3ad001900f94298965e1cad1c772b87f9cfea011/regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62", size = 773197, upload-time = "2024-11-06T20:09:24.092Z" }, + { url = "https://files.pythonhosted.org/packages/45/3f/ef9589aba93e084cd3f8471fded352826dcae8489b650d0b9b27bc5bba8a/regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e", size = 261714, upload-time = "2024-11-06T20:09:26.36Z" }, + { url = "https://files.pythonhosted.org/packages/42/7e/5f1b92c8468290c465fd50c5318da64319133231415a8aa6ea5ab995a815/regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519", size = 274042, upload-time = "2024-11-06T20:09:28.762Z" }, + { url = "https://files.pythonhosted.org/packages/58/58/7e4d9493a66c88a7da6d205768119f51af0f684fe7be7bac8328e217a52c/regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638", size = 482669, upload-time = "2024-11-06T20:09:31.064Z" }, + { url = "https://files.pythonhosted.org/packages/34/4c/8f8e631fcdc2ff978609eaeef1d6994bf2f028b59d9ac67640ed051f1218/regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7", size = 287684, upload-time = "2024-11-06T20:09:32.915Z" }, + { url = "https://files.pythonhosted.org/packages/c5/1b/f0e4d13e6adf866ce9b069e191f303a30ab1277e037037a365c3aad5cc9c/regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20", size = 284589, upload-time = "2024-11-06T20:09:35.504Z" }, + { url = "https://files.pythonhosted.org/packages/25/4d/ab21047f446693887f25510887e6820b93f791992994f6498b0318904d4a/regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114", size = 792121, upload-time = "2024-11-06T20:09:37.701Z" }, + { url = "https://files.pythonhosted.org/packages/45/ee/c867e15cd894985cb32b731d89576c41a4642a57850c162490ea34b78c3b/regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3", size = 831275, upload-time = "2024-11-06T20:09:40.371Z" }, + { url = "https://files.pythonhosted.org/packages/b3/12/b0f480726cf1c60f6536fa5e1c95275a77624f3ac8fdccf79e6727499e28/regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f", size = 818257, upload-time = "2024-11-06T20:09:43.059Z" }, + { url = "https://files.pythonhosted.org/packages/bf/ce/0d0e61429f603bac433910d99ef1a02ce45a8967ffbe3cbee48599e62d88/regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0", size = 792727, upload-time = "2024-11-06T20:09:48.19Z" }, + { url = "https://files.pythonhosted.org/packages/e4/c1/243c83c53d4a419c1556f43777ccb552bccdf79d08fda3980e4e77dd9137/regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55", size = 780667, upload-time = "2024-11-06T20:09:49.828Z" }, + { url = "https://files.pythonhosted.org/packages/c5/f4/75eb0dd4ce4b37f04928987f1d22547ddaf6c4bae697623c1b05da67a8aa/regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89", size = 776963, upload-time = "2024-11-06T20:09:51.819Z" }, + { url = "https://files.pythonhosted.org/packages/16/5d/95c568574e630e141a69ff8a254c2f188b4398e813c40d49228c9bbd9875/regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d", size = 784700, upload-time = "2024-11-06T20:09:53.982Z" }, + { url = "https://files.pythonhosted.org/packages/8e/b5/f8495c7917f15cc6fee1e7f395e324ec3e00ab3c665a7dc9d27562fd5290/regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34", size = 848592, upload-time = "2024-11-06T20:09:56.222Z" }, + { url = "https://files.pythonhosted.org/packages/1c/80/6dd7118e8cb212c3c60b191b932dc57db93fb2e36fb9e0e92f72a5909af9/regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d", size = 852929, upload-time = "2024-11-06T20:09:58.642Z" }, + { url = "https://files.pythonhosted.org/packages/11/9b/5a05d2040297d2d254baf95eeeb6df83554e5e1df03bc1a6687fc4ba1f66/regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45", size = 781213, upload-time = "2024-11-06T20:10:00.867Z" }, + { url = "https://files.pythonhosted.org/packages/26/b7/b14e2440156ab39e0177506c08c18accaf2b8932e39fb092074de733d868/regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9", size = 261734, upload-time = "2024-11-06T20:10:03.361Z" }, + { url = "https://files.pythonhosted.org/packages/80/32/763a6cc01d21fb3819227a1cc3f60fd251c13c37c27a73b8ff4315433a8e/regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60", size = 274052, upload-time = "2024-11-06T20:10:05.179Z" }, + { url = "https://files.pythonhosted.org/packages/ba/30/9a87ce8336b172cc232a0db89a3af97929d06c11ceaa19d97d84fa90a8f8/regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a", size = 483781, upload-time = "2024-11-06T20:10:07.07Z" }, + { url = "https://files.pythonhosted.org/packages/01/e8/00008ad4ff4be8b1844786ba6636035f7ef926db5686e4c0f98093612add/regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9", size = 288455, upload-time = "2024-11-06T20:10:09.117Z" }, + { url = "https://files.pythonhosted.org/packages/60/85/cebcc0aff603ea0a201667b203f13ba75d9fc8668fab917ac5b2de3967bc/regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2", size = 284759, upload-time = "2024-11-06T20:10:11.155Z" }, + { url = "https://files.pythonhosted.org/packages/94/2b/701a4b0585cb05472a4da28ee28fdfe155f3638f5e1ec92306d924e5faf0/regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4", size = 794976, upload-time = "2024-11-06T20:10:13.24Z" }, + { url = "https://files.pythonhosted.org/packages/4b/bf/fa87e563bf5fee75db8915f7352e1887b1249126a1be4813837f5dbec965/regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577", size = 833077, upload-time = "2024-11-06T20:10:15.37Z" }, + { url = "https://files.pythonhosted.org/packages/a1/56/7295e6bad94b047f4d0834e4779491b81216583c00c288252ef625c01d23/regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3", size = 823160, upload-time = "2024-11-06T20:10:19.027Z" }, + { url = "https://files.pythonhosted.org/packages/fb/13/e3b075031a738c9598c51cfbc4c7879e26729c53aa9cca59211c44235314/regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e", size = 796896, upload-time = "2024-11-06T20:10:21.85Z" }, + { url = "https://files.pythonhosted.org/packages/24/56/0b3f1b66d592be6efec23a795b37732682520b47c53da5a32c33ed7d84e3/regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe", size = 783997, upload-time = "2024-11-06T20:10:24.329Z" }, + { url = "https://files.pythonhosted.org/packages/f9/a1/eb378dada8b91c0e4c5f08ffb56f25fcae47bf52ad18f9b2f33b83e6d498/regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e", size = 781725, upload-time = "2024-11-06T20:10:28.067Z" }, + { url = "https://files.pythonhosted.org/packages/83/f2/033e7dec0cfd6dda93390089864732a3409246ffe8b042e9554afa9bff4e/regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29", size = 789481, upload-time = "2024-11-06T20:10:31.612Z" }, + { url = "https://files.pythonhosted.org/packages/83/23/15d4552ea28990a74e7696780c438aadd73a20318c47e527b47a4a5a596d/regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39", size = 852896, upload-time = "2024-11-06T20:10:34.054Z" }, + { url = "https://files.pythonhosted.org/packages/e3/39/ed4416bc90deedbfdada2568b2cb0bc1fdb98efe11f5378d9892b2a88f8f/regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51", size = 860138, upload-time = "2024-11-06T20:10:36.142Z" }, + { url = "https://files.pythonhosted.org/packages/93/2d/dd56bb76bd8e95bbce684326302f287455b56242a4f9c61f1bc76e28360e/regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad", size = 787692, upload-time = "2024-11-06T20:10:38.394Z" }, + { url = "https://files.pythonhosted.org/packages/0b/55/31877a249ab7a5156758246b9c59539abbeba22461b7d8adc9e8475ff73e/regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54", size = 262135, upload-time = "2024-11-06T20:10:40.367Z" }, + { url = "https://files.pythonhosted.org/packages/38/ec/ad2d7de49a600cdb8dd78434a1aeffe28b9d6fc42eb36afab4a27ad23384/regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b", size = 273567, upload-time = "2024-11-06T20:10:43.467Z" }, + { url = "https://files.pythonhosted.org/packages/90/73/bcb0e36614601016552fa9344544a3a2ae1809dc1401b100eab02e772e1f/regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84", size = 483525, upload-time = "2024-11-06T20:10:45.19Z" }, + { url = "https://files.pythonhosted.org/packages/0f/3f/f1a082a46b31e25291d830b369b6b0c5576a6f7fb89d3053a354c24b8a83/regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4", size = 288324, upload-time = "2024-11-06T20:10:47.177Z" }, + { url = "https://files.pythonhosted.org/packages/09/c9/4e68181a4a652fb3ef5099e077faf4fd2a694ea6e0f806a7737aff9e758a/regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0", size = 284617, upload-time = "2024-11-06T20:10:49.312Z" }, + { url = "https://files.pythonhosted.org/packages/fc/fd/37868b75eaf63843165f1d2122ca6cb94bfc0271e4428cf58c0616786dce/regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0", size = 795023, upload-time = "2024-11-06T20:10:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/c4/7c/d4cd9c528502a3dedb5c13c146e7a7a539a3853dc20209c8e75d9ba9d1b2/regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7", size = 833072, upload-time = "2024-11-06T20:10:52.926Z" }, + { url = "https://files.pythonhosted.org/packages/4f/db/46f563a08f969159c5a0f0e722260568425363bea43bb7ae370becb66a67/regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7", size = 823130, upload-time = "2024-11-06T20:10:54.828Z" }, + { url = "https://files.pythonhosted.org/packages/db/60/1eeca2074f5b87df394fccaa432ae3fc06c9c9bfa97c5051aed70e6e00c2/regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c", size = 796857, upload-time = "2024-11-06T20:10:56.634Z" }, + { url = "https://files.pythonhosted.org/packages/10/db/ac718a08fcee981554d2f7bb8402f1faa7e868c1345c16ab1ebec54b0d7b/regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3", size = 784006, upload-time = "2024-11-06T20:10:59.369Z" }, + { url = "https://files.pythonhosted.org/packages/c2/41/7da3fe70216cea93144bf12da2b87367590bcf07db97604edeea55dac9ad/regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07", size = 781650, upload-time = "2024-11-06T20:11:02.042Z" }, + { url = "https://files.pythonhosted.org/packages/a7/d5/880921ee4eec393a4752e6ab9f0fe28009435417c3102fc413f3fe81c4e5/regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e", size = 789545, upload-time = "2024-11-06T20:11:03.933Z" }, + { url = "https://files.pythonhosted.org/packages/dc/96/53770115e507081122beca8899ab7f5ae28ae790bfcc82b5e38976df6a77/regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6", size = 853045, upload-time = "2024-11-06T20:11:06.497Z" }, + { url = "https://files.pythonhosted.org/packages/31/d3/1372add5251cc2d44b451bd94f43b2ec78e15a6e82bff6a290ef9fd8f00a/regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4", size = 860182, upload-time = "2024-11-06T20:11:09.06Z" }, + { url = "https://files.pythonhosted.org/packages/ed/e3/c446a64984ea9f69982ba1a69d4658d5014bc7a0ea468a07e1a1265db6e2/regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d", size = 787733, upload-time = "2024-11-06T20:11:11.256Z" }, + { url = "https://files.pythonhosted.org/packages/2b/f1/e40c8373e3480e4f29f2692bd21b3e05f296d3afebc7e5dcf21b9756ca1c/regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff", size = 262122, upload-time = "2024-11-06T20:11:13.161Z" }, + { url = "https://files.pythonhosted.org/packages/45/94/bc295babb3062a731f52621cdc992d123111282e291abaf23faa413443ea/regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a", size = 273545, upload-time = "2024-11-06T20:11:15Z" }, ] [[package]] @@ -1518,9 +1518,9 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e1/0a/929373653770d8a0d7ea76c37de6e41f11eb07559b103b1c02cafb3f7cf8/requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422", size = 135258 } +sdist = { url = "https://files.pythonhosted.org/packages/e1/0a/929373653770d8a0d7ea76c37de6e41f11eb07559b103b1c02cafb3f7cf8/requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422", size = 135258, upload-time = "2025-06-09T16:43:07.34Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847 }, + { url = "https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847, upload-time = "2025-06-09T16:43:05.728Z" }, ] [[package]] @@ -1532,9 +1532,9 @@ dependencies = [ { name = "pygments" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a1/53/830aa4c3066a8ab0ae9a9955976fb770fe9c6102117c8ec4ab3ea62d89e8/rich-14.0.0.tar.gz", hash = "sha256:82f1bc23a6a21ebca4ae0c45af9bdbc492ed20231dcb63f297d6d1021a9d5725", size = 224078 } +sdist = { url = "https://files.pythonhosted.org/packages/a1/53/830aa4c3066a8ab0ae9a9955976fb770fe9c6102117c8ec4ab3ea62d89e8/rich-14.0.0.tar.gz", hash = "sha256:82f1bc23a6a21ebca4ae0c45af9bdbc492ed20231dcb63f297d6d1021a9d5725", size = 224078, upload-time = "2025-03-30T14:15:14.23Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0d/9b/63f4c7ebc259242c89b3acafdb37b41d1185c07ff0011164674e9076b491/rich-14.0.0-py3-none-any.whl", hash = "sha256:1c9491e1951aac09caffd42f448ee3d04e58923ffe14993f6e83068dc395d7e0", size = 243229 }, + { url = "https://files.pythonhosted.org/packages/0d/9b/63f4c7ebc259242c89b3acafdb37b41d1185c07ff0011164674e9076b491/rich-14.0.0-py3-none-any.whl", hash = "sha256:1c9491e1951aac09caffd42f448ee3d04e58923ffe14993f6e83068dc395d7e0", size = 243229, upload-time = "2025-03-30T14:15:12.283Z" }, ] [[package]] @@ -1546,9 +1546,9 @@ dependencies = [ { name = "rich" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5b/7a/cb48b7024b247631ce39b1f14a0f1abedf311fb27b892b0e0387d809d4b5/rich_toolkit-0.14.7.tar.gz", hash = "sha256:6cca5a68850cc5778915f528eb785662c27ba3b4b2624612cce8340fa9701c5e", size = 104977 } +sdist = { url = "https://files.pythonhosted.org/packages/5b/7a/cb48b7024b247631ce39b1f14a0f1abedf311fb27b892b0e0387d809d4b5/rich_toolkit-0.14.7.tar.gz", hash = "sha256:6cca5a68850cc5778915f528eb785662c27ba3b4b2624612cce8340fa9701c5e", size = 104977, upload-time = "2025-05-27T15:48:09.377Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0f/2e/95fde5b818dac9a37683ea064096323f593442d0f6358923c5f635974393/rich_toolkit-0.14.7-py3-none-any.whl", hash = "sha256:def05cc6e0f1176d6263b6a26648f16a62c4563b277ca2f8538683acdba1e0da", size = 24870 }, + { url = "https://files.pythonhosted.org/packages/0f/2e/95fde5b818dac9a37683ea064096323f593442d0f6358923c5f635974393/rich_toolkit-0.14.7-py3-none-any.whl", hash = "sha256:def05cc6e0f1176d6263b6a26648f16a62c4563b277ca2f8538683acdba1e0da", size = 24870, upload-time = "2025-05-27T15:48:07.942Z" }, ] [[package]] @@ -1558,52 +1558,52 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "eth-utils" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1b/2d/439b0728a92964a04d9c88ea1ca9ebb128893fbbd5834faa31f987f2fd4c/rlp-4.1.0.tar.gz", hash = "sha256:be07564270a96f3e225e2c107db263de96b5bc1f27722d2855bd3459a08e95a9", size = 33429 } +sdist = { url = "https://files.pythonhosted.org/packages/1b/2d/439b0728a92964a04d9c88ea1ca9ebb128893fbbd5834faa31f987f2fd4c/rlp-4.1.0.tar.gz", hash = "sha256:be07564270a96f3e225e2c107db263de96b5bc1f27722d2855bd3459a08e95a9", size = 33429, upload-time = "2025-02-04T22:05:59.089Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/99/fb/e4c0ced9893b84ac95b7181d69a9786ce5879aeb3bbbcbba80a164f85d6a/rlp-4.1.0-py3-none-any.whl", hash = "sha256:8eca394c579bad34ee0b937aecb96a57052ff3716e19c7a578883e767bc5da6f", size = 19973 }, + { url = "https://files.pythonhosted.org/packages/99/fb/e4c0ced9893b84ac95b7181d69a9786ce5879aeb3bbbcbba80a164f85d6a/rlp-4.1.0-py3-none-any.whl", hash = "sha256:8eca394c579bad34ee0b937aecb96a57052ff3716e19c7a578883e767bc5da6f", size = 19973, upload-time = "2025-02-04T22:05:57.05Z" }, ] [[package]] name = "ruff" version = "0.11.13" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ed/da/9c6f995903b4d9474b39da91d2d626659af3ff1eeb43e9ae7c119349dba6/ruff-0.11.13.tar.gz", hash = "sha256:26fa247dc68d1d4e72c179e08889a25ac0c7ba4d78aecfc835d49cbfd60bf514", size = 4282054 } +sdist = { url = "https://files.pythonhosted.org/packages/ed/da/9c6f995903b4d9474b39da91d2d626659af3ff1eeb43e9ae7c119349dba6/ruff-0.11.13.tar.gz", hash = "sha256:26fa247dc68d1d4e72c179e08889a25ac0c7ba4d78aecfc835d49cbfd60bf514", size = 4282054, upload-time = "2025-06-05T21:00:15.721Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7d/ce/a11d381192966e0b4290842cc8d4fac7dc9214ddf627c11c1afff87da29b/ruff-0.11.13-py3-none-linux_armv6l.whl", hash = "sha256:4bdfbf1240533f40042ec00c9e09a3aade6f8c10b6414cf11b519488d2635d46", size = 10292516 }, - { url = "https://files.pythonhosted.org/packages/78/db/87c3b59b0d4e753e40b6a3b4a2642dfd1dcaefbff121ddc64d6c8b47ba00/ruff-0.11.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:aef9c9ed1b5ca28bb15c7eac83b8670cf3b20b478195bd49c8d756ba0a36cf48", size = 11106083 }, - { url = "https://files.pythonhosted.org/packages/77/79/d8cec175856ff810a19825d09ce700265f905c643c69f45d2b737e4a470a/ruff-0.11.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:53b15a9dfdce029c842e9a5aebc3855e9ab7771395979ff85b7c1dedb53ddc2b", size = 10436024 }, - { url = "https://files.pythonhosted.org/packages/8b/5b/f6d94f2980fa1ee854b41568368a2e1252681b9238ab2895e133d303538f/ruff-0.11.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab153241400789138d13f362c43f7edecc0edfffce2afa6a68434000ecd8f69a", size = 10646324 }, - { url = "https://files.pythonhosted.org/packages/6c/9c/b4c2acf24ea4426016d511dfdc787f4ce1ceb835f3c5fbdbcb32b1c63bda/ruff-0.11.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c51f93029d54a910d3d24f7dd0bb909e31b6cd989a5e4ac513f4eb41629f0dc", size = 10174416 }, - { url = "https://files.pythonhosted.org/packages/f3/10/e2e62f77c65ede8cd032c2ca39c41f48feabedb6e282bfd6073d81bb671d/ruff-0.11.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1808b3ed53e1a777c2ef733aca9051dc9bf7c99b26ece15cb59a0320fbdbd629", size = 11724197 }, - { url = "https://files.pythonhosted.org/packages/bb/f0/466fe8469b85c561e081d798c45f8a1d21e0b4a5ef795a1d7f1a9a9ec182/ruff-0.11.13-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d28ce58b5ecf0f43c1b71edffabe6ed7f245d5336b17805803312ec9bc665933", size = 12511615 }, - { url = "https://files.pythonhosted.org/packages/17/0e/cefe778b46dbd0cbcb03a839946c8f80a06f7968eb298aa4d1a4293f3448/ruff-0.11.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55e4bc3a77842da33c16d55b32c6cac1ec5fb0fbec9c8c513bdce76c4f922165", size = 12117080 }, - { url = "https://files.pythonhosted.org/packages/5d/2c/caaeda564cbe103bed145ea557cb86795b18651b0f6b3ff6a10e84e5a33f/ruff-0.11.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:633bf2c6f35678c56ec73189ba6fa19ff1c5e4807a78bf60ef487b9dd272cc71", size = 11326315 }, - { url = "https://files.pythonhosted.org/packages/75/f0/782e7d681d660eda8c536962920c41309e6dd4ebcea9a2714ed5127d44bd/ruff-0.11.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ffbc82d70424b275b089166310448051afdc6e914fdab90e08df66c43bb5ca9", size = 11555640 }, - { url = "https://files.pythonhosted.org/packages/5d/d4/3d580c616316c7f07fb3c99dbecfe01fbaea7b6fd9a82b801e72e5de742a/ruff-0.11.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4a9ddd3ec62a9a89578c85842b836e4ac832d4a2e0bfaad3b02243f930ceafcc", size = 10507364 }, - { url = "https://files.pythonhosted.org/packages/5a/dc/195e6f17d7b3ea6b12dc4f3e9de575db7983db187c378d44606e5d503319/ruff-0.11.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d237a496e0778d719efb05058c64d28b757c77824e04ffe8796c7436e26712b7", size = 10141462 }, - { url = "https://files.pythonhosted.org/packages/f4/8e/39a094af6967faa57ecdeacb91bedfb232474ff8c3d20f16a5514e6b3534/ruff-0.11.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:26816a218ca6ef02142343fd24c70f7cd8c5aa6c203bca284407adf675984432", size = 11121028 }, - { url = "https://files.pythonhosted.org/packages/5a/c0/b0b508193b0e8a1654ec683ebab18d309861f8bd64e3a2f9648b80d392cb/ruff-0.11.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:51c3f95abd9331dc5b87c47ac7f376db5616041173826dfd556cfe3d4977f492", size = 11602992 }, - { url = "https://files.pythonhosted.org/packages/7c/91/263e33ab93ab09ca06ce4f8f8547a858cc198072f873ebc9be7466790bae/ruff-0.11.13-py3-none-win32.whl", hash = "sha256:96c27935418e4e8e77a26bb05962817f28b8ef3843a6c6cc49d8783b5507f250", size = 10474944 }, - { url = "https://files.pythonhosted.org/packages/46/f4/7c27734ac2073aae8efb0119cae6931b6fb48017adf048fdf85c19337afc/ruff-0.11.13-py3-none-win_amd64.whl", hash = "sha256:29c3189895a8a6a657b7af4e97d330c8a3afd2c9c8f46c81e2fc5a31866517e3", size = 11548669 }, - { url = "https://files.pythonhosted.org/packages/ec/bf/b273dd11673fed8a6bd46032c0ea2a04b2ac9bfa9c628756a5856ba113b0/ruff-0.11.13-py3-none-win_arm64.whl", hash = "sha256:b4385285e9179d608ff1d2fb9922062663c658605819a6876d8beef0c30b7f3b", size = 10683928 }, + { url = "https://files.pythonhosted.org/packages/7d/ce/a11d381192966e0b4290842cc8d4fac7dc9214ddf627c11c1afff87da29b/ruff-0.11.13-py3-none-linux_armv6l.whl", hash = "sha256:4bdfbf1240533f40042ec00c9e09a3aade6f8c10b6414cf11b519488d2635d46", size = 10292516, upload-time = "2025-06-05T20:59:32.944Z" }, + { url = "https://files.pythonhosted.org/packages/78/db/87c3b59b0d4e753e40b6a3b4a2642dfd1dcaefbff121ddc64d6c8b47ba00/ruff-0.11.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:aef9c9ed1b5ca28bb15c7eac83b8670cf3b20b478195bd49c8d756ba0a36cf48", size = 11106083, upload-time = "2025-06-05T20:59:37.03Z" }, + { url = "https://files.pythonhosted.org/packages/77/79/d8cec175856ff810a19825d09ce700265f905c643c69f45d2b737e4a470a/ruff-0.11.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:53b15a9dfdce029c842e9a5aebc3855e9ab7771395979ff85b7c1dedb53ddc2b", size = 10436024, upload-time = "2025-06-05T20:59:39.741Z" }, + { url = "https://files.pythonhosted.org/packages/8b/5b/f6d94f2980fa1ee854b41568368a2e1252681b9238ab2895e133d303538f/ruff-0.11.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab153241400789138d13f362c43f7edecc0edfffce2afa6a68434000ecd8f69a", size = 10646324, upload-time = "2025-06-05T20:59:42.185Z" }, + { url = "https://files.pythonhosted.org/packages/6c/9c/b4c2acf24ea4426016d511dfdc787f4ce1ceb835f3c5fbdbcb32b1c63bda/ruff-0.11.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c51f93029d54a910d3d24f7dd0bb909e31b6cd989a5e4ac513f4eb41629f0dc", size = 10174416, upload-time = "2025-06-05T20:59:44.319Z" }, + { url = "https://files.pythonhosted.org/packages/f3/10/e2e62f77c65ede8cd032c2ca39c41f48feabedb6e282bfd6073d81bb671d/ruff-0.11.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1808b3ed53e1a777c2ef733aca9051dc9bf7c99b26ece15cb59a0320fbdbd629", size = 11724197, upload-time = "2025-06-05T20:59:46.935Z" }, + { url = "https://files.pythonhosted.org/packages/bb/f0/466fe8469b85c561e081d798c45f8a1d21e0b4a5ef795a1d7f1a9a9ec182/ruff-0.11.13-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d28ce58b5ecf0f43c1b71edffabe6ed7f245d5336b17805803312ec9bc665933", size = 12511615, upload-time = "2025-06-05T20:59:49.534Z" }, + { url = "https://files.pythonhosted.org/packages/17/0e/cefe778b46dbd0cbcb03a839946c8f80a06f7968eb298aa4d1a4293f3448/ruff-0.11.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55e4bc3a77842da33c16d55b32c6cac1ec5fb0fbec9c8c513bdce76c4f922165", size = 12117080, upload-time = "2025-06-05T20:59:51.654Z" }, + { url = "https://files.pythonhosted.org/packages/5d/2c/caaeda564cbe103bed145ea557cb86795b18651b0f6b3ff6a10e84e5a33f/ruff-0.11.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:633bf2c6f35678c56ec73189ba6fa19ff1c5e4807a78bf60ef487b9dd272cc71", size = 11326315, upload-time = "2025-06-05T20:59:54.469Z" }, + { url = "https://files.pythonhosted.org/packages/75/f0/782e7d681d660eda8c536962920c41309e6dd4ebcea9a2714ed5127d44bd/ruff-0.11.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ffbc82d70424b275b089166310448051afdc6e914fdab90e08df66c43bb5ca9", size = 11555640, upload-time = "2025-06-05T20:59:56.986Z" }, + { url = "https://files.pythonhosted.org/packages/5d/d4/3d580c616316c7f07fb3c99dbecfe01fbaea7b6fd9a82b801e72e5de742a/ruff-0.11.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4a9ddd3ec62a9a89578c85842b836e4ac832d4a2e0bfaad3b02243f930ceafcc", size = 10507364, upload-time = "2025-06-05T20:59:59.154Z" }, + { url = "https://files.pythonhosted.org/packages/5a/dc/195e6f17d7b3ea6b12dc4f3e9de575db7983db187c378d44606e5d503319/ruff-0.11.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d237a496e0778d719efb05058c64d28b757c77824e04ffe8796c7436e26712b7", size = 10141462, upload-time = "2025-06-05T21:00:01.481Z" }, + { url = "https://files.pythonhosted.org/packages/f4/8e/39a094af6967faa57ecdeacb91bedfb232474ff8c3d20f16a5514e6b3534/ruff-0.11.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:26816a218ca6ef02142343fd24c70f7cd8c5aa6c203bca284407adf675984432", size = 11121028, upload-time = "2025-06-05T21:00:04.06Z" }, + { url = "https://files.pythonhosted.org/packages/5a/c0/b0b508193b0e8a1654ec683ebab18d309861f8bd64e3a2f9648b80d392cb/ruff-0.11.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:51c3f95abd9331dc5b87c47ac7f376db5616041173826dfd556cfe3d4977f492", size = 11602992, upload-time = "2025-06-05T21:00:06.249Z" }, + { url = "https://files.pythonhosted.org/packages/7c/91/263e33ab93ab09ca06ce4f8f8547a858cc198072f873ebc9be7466790bae/ruff-0.11.13-py3-none-win32.whl", hash = "sha256:96c27935418e4e8e77a26bb05962817f28b8ef3843a6c6cc49d8783b5507f250", size = 10474944, upload-time = "2025-06-05T21:00:08.459Z" }, + { url = "https://files.pythonhosted.org/packages/46/f4/7c27734ac2073aae8efb0119cae6931b6fb48017adf048fdf85c19337afc/ruff-0.11.13-py3-none-win_amd64.whl", hash = "sha256:29c3189895a8a6a657b7af4e97d330c8a3afd2c9c8f46c81e2fc5a31866517e3", size = 11548669, upload-time = "2025-06-05T21:00:11.147Z" }, + { url = "https://files.pythonhosted.org/packages/ec/bf/b273dd11673fed8a6bd46032c0ea2a04b2ac9bfa9c628756a5856ba113b0/ruff-0.11.13-py3-none-win_arm64.whl", hash = "sha256:b4385285e9179d608ff1d2fb9922062663c658605819a6876d8beef0c30b7f3b", size = 10683928, upload-time = "2025-06-05T21:00:13.758Z" }, ] [[package]] name = "shellingham" version = "1.5.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310 } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755 }, + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, ] [[package]] name = "sniffio" version = "1.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, ] [[package]] @@ -1613,57 +1613,57 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ce/20/08dfcd9c983f6a6f4a1000d934b9e6d626cff8d2eeb77a89a68eef20a2b7/starlette-0.46.2.tar.gz", hash = "sha256:7f7361f34eed179294600af672f565727419830b54b7b084efe44bb82d2fccd5", size = 2580846 } +sdist = { url = "https://files.pythonhosted.org/packages/ce/20/08dfcd9c983f6a6f4a1000d934b9e6d626cff8d2eeb77a89a68eef20a2b7/starlette-0.46.2.tar.gz", hash = "sha256:7f7361f34eed179294600af672f565727419830b54b7b084efe44bb82d2fccd5", size = 2580846, upload-time = "2025-04-13T13:56:17.942Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/0c/9d30a4ebeb6db2b25a841afbb80f6ef9a854fc3b41be131d249a977b4959/starlette-0.46.2-py3-none-any.whl", hash = "sha256:595633ce89f8ffa71a015caed34a5b2dc1c0cdb3f0f1fbd1e69339cf2abeec35", size = 72037 }, + { url = "https://files.pythonhosted.org/packages/8b/0c/9d30a4ebeb6db2b25a841afbb80f6ef9a854fc3b41be131d249a977b4959/starlette-0.46.2-py3-none-any.whl", hash = "sha256:595633ce89f8ffa71a015caed34a5b2dc1c0cdb3f0f1fbd1e69339cf2abeec35", size = 72037, upload-time = "2025-04-13T13:56:16.21Z" }, ] [[package]] name = "tomli" version = "2.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077 }, - { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429 }, - { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067 }, - { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030 }, - { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898 }, - { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894 }, - { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319 }, - { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273 }, - { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310 }, - { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309 }, - { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762 }, - { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453 }, - { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486 }, - { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349 }, - { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159 }, - { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243 }, - { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645 }, - { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584 }, - { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875 }, - { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418 }, - { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708 }, - { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582 }, - { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543 }, - { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691 }, - { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170 }, - { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530 }, - { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666 }, - { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954 }, - { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724 }, - { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383 }, - { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 }, +sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175, upload-time = "2024-11-27T22:38:36.873Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077, upload-time = "2024-11-27T22:37:54.956Z" }, + { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429, upload-time = "2024-11-27T22:37:56.698Z" }, + { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067, upload-time = "2024-11-27T22:37:57.63Z" }, + { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030, upload-time = "2024-11-27T22:37:59.344Z" }, + { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898, upload-time = "2024-11-27T22:38:00.429Z" }, + { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894, upload-time = "2024-11-27T22:38:02.094Z" }, + { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319, upload-time = "2024-11-27T22:38:03.206Z" }, + { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273, upload-time = "2024-11-27T22:38:04.217Z" }, + { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310, upload-time = "2024-11-27T22:38:05.908Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309, upload-time = "2024-11-27T22:38:06.812Z" }, + { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762, upload-time = "2024-11-27T22:38:07.731Z" }, + { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453, upload-time = "2024-11-27T22:38:09.384Z" }, + { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486, upload-time = "2024-11-27T22:38:10.329Z" }, + { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349, upload-time = "2024-11-27T22:38:11.443Z" }, + { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159, upload-time = "2024-11-27T22:38:13.099Z" }, + { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243, upload-time = "2024-11-27T22:38:14.766Z" }, + { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645, upload-time = "2024-11-27T22:38:15.843Z" }, + { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584, upload-time = "2024-11-27T22:38:17.645Z" }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875, upload-time = "2024-11-27T22:38:19.159Z" }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418, upload-time = "2024-11-27T22:38:20.064Z" }, + { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708, upload-time = "2024-11-27T22:38:21.659Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582, upload-time = "2024-11-27T22:38:22.693Z" }, + { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543, upload-time = "2024-11-27T22:38:24.367Z" }, + { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691, upload-time = "2024-11-27T22:38:26.081Z" }, + { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170, upload-time = "2024-11-27T22:38:27.921Z" }, + { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530, upload-time = "2024-11-27T22:38:29.591Z" }, + { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666, upload-time = "2024-11-27T22:38:30.639Z" }, + { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954, upload-time = "2024-11-27T22:38:31.702Z" }, + { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724, upload-time = "2024-11-27T22:38:32.837Z" }, + { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383, upload-time = "2024-11-27T22:38:34.455Z" }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257, upload-time = "2024-11-27T22:38:35.385Z" }, ] [[package]] name = "toolz" version = "1.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8a/0b/d80dfa675bf592f636d1ea0b835eab4ec8df6e9415d8cfd766df54456123/toolz-1.0.0.tar.gz", hash = "sha256:2c86e3d9a04798ac556793bced838816296a2f085017664e4995cb40a1047a02", size = 66790 } +sdist = { url = "https://files.pythonhosted.org/packages/8a/0b/d80dfa675bf592f636d1ea0b835eab4ec8df6e9415d8cfd766df54456123/toolz-1.0.0.tar.gz", hash = "sha256:2c86e3d9a04798ac556793bced838816296a2f085017664e4995cb40a1047a02", size = 66790, upload-time = "2024-10-04T16:17:04.001Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/03/98/eb27cc78ad3af8e302c9d8ff4977f5026676e130d28dd7578132a457170c/toolz-1.0.0-py3-none-any.whl", hash = "sha256:292c8f1c4e7516bf9086f8850935c799a874039c8bcf959d47b600e4c44a6236", size = 56383 }, + { url = "https://files.pythonhosted.org/packages/03/98/eb27cc78ad3af8e302c9d8ff4977f5026676e130d28dd7578132a457170c/toolz-1.0.0-py3-none-any.whl", hash = "sha256:292c8f1c4e7516bf9086f8850935c799a874039c8bcf959d47b600e4c44a6236", size = 56383, upload-time = "2024-10-04T16:17:01.533Z" }, ] [[package]] @@ -1676,9 +1676,9 @@ dependencies = [ { name = "shellingham" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c5/8c/7d682431efca5fd290017663ea4588bf6f2c6aad085c7f108c5dbc316e70/typer-0.16.0.tar.gz", hash = "sha256:af377ffaee1dbe37ae9440cb4e8f11686ea5ce4e9bae01b84ae7c63b87f1dd3b", size = 102625 } +sdist = { url = "https://files.pythonhosted.org/packages/c5/8c/7d682431efca5fd290017663ea4588bf6f2c6aad085c7f108c5dbc316e70/typer-0.16.0.tar.gz", hash = "sha256:af377ffaee1dbe37ae9440cb4e8f11686ea5ce4e9bae01b84ae7c63b87f1dd3b", size = 102625, upload-time = "2025-05-26T14:30:31.824Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/42/3efaf858001d2c2913de7f354563e3a3a2f0decae3efe98427125a8f441e/typer-0.16.0-py3-none-any.whl", hash = "sha256:1f79bed11d4d02d4310e3c1b7ba594183bcedb0ac73b27a9e5f28f6fb5b98855", size = 46317 }, + { url = "https://files.pythonhosted.org/packages/76/42/3efaf858001d2c2913de7f354563e3a3a2f0decae3efe98427125a8f441e/typer-0.16.0-py3-none-any.whl", hash = "sha256:1f79bed11d4d02d4310e3c1b7ba594183bcedb0ac73b27a9e5f28f6fb5b98855", size = 46317, upload-time = "2025-05-26T14:30:30.523Z" }, ] [[package]] @@ -1688,18 +1688,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6d/7f/73b3a04a53b0fd2a911d4ec517940ecd6600630b559e4505cc7b68beb5a0/types_requests-2.32.4.20250611.tar.gz", hash = "sha256:741c8777ed6425830bf51e54d6abe245f79b4dcb9019f1622b773463946bf826", size = 23118 } +sdist = { url = "https://files.pythonhosted.org/packages/6d/7f/73b3a04a53b0fd2a911d4ec517940ecd6600630b559e4505cc7b68beb5a0/types_requests-2.32.4.20250611.tar.gz", hash = "sha256:741c8777ed6425830bf51e54d6abe245f79b4dcb9019f1622b773463946bf826", size = 23118, upload-time = "2025-06-11T03:11:41.272Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/ea/0be9258c5a4fa1ba2300111aa5a0767ee6d18eb3fd20e91616c12082284d/types_requests-2.32.4.20250611-py3-none-any.whl", hash = "sha256:ad2fe5d3b0cb3c2c902c8815a70e7fb2302c4b8c1f77bdcd738192cdb3878072", size = 20643 }, + { url = "https://files.pythonhosted.org/packages/3d/ea/0be9258c5a4fa1ba2300111aa5a0767ee6d18eb3fd20e91616c12082284d/types_requests-2.32.4.20250611-py3-none-any.whl", hash = "sha256:ad2fe5d3b0cb3c2c902c8815a70e7fb2302c4b8c1f77bdcd738192cdb3878072", size = 20643, upload-time = "2025-06-11T03:11:40.186Z" }, ] [[package]] name = "typing-extensions" version = "4.14.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d1/bc/51647cd02527e87d05cb083ccc402f93e441606ff1f01739a62c8ad09ba5/typing_extensions-4.14.0.tar.gz", hash = "sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4", size = 107423 } +sdist = { url = "https://files.pythonhosted.org/packages/d1/bc/51647cd02527e87d05cb083ccc402f93e441606ff1f01739a62c8ad09ba5/typing_extensions-4.14.0.tar.gz", hash = "sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4", size = 107423, upload-time = "2025-06-02T14:52:11.399Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/69/e0/552843e0d356fbb5256d21449fa957fa4eff3bbc135a74a691ee70c7c5da/typing_extensions-4.14.0-py3-none-any.whl", hash = "sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af", size = 43839 }, + { url = "https://files.pythonhosted.org/packages/69/e0/552843e0d356fbb5256d21449fa957fa4eff3bbc135a74a691ee70c7c5da/typing_extensions-4.14.0-py3-none-any.whl", hash = "sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af", size = 43839, upload-time = "2025-06-02T14:52:10.026Z" }, ] [[package]] @@ -1709,18 +1709,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726 } +sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552 }, + { url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552, upload-time = "2025-05-21T18:55:22.152Z" }, ] [[package]] name = "urllib3" version = "2.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672 } +sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672, upload-time = "2025-04-10T15:23:39.232Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680 }, + { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680, upload-time = "2025-04-10T15:23:37.377Z" }, ] [[package]] @@ -1732,9 +1732,9 @@ dependencies = [ { name = "h11" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/de/ad/713be230bcda622eaa35c28f0d328c3675c371238470abdea52417f17a8e/uvicorn-0.34.3.tar.gz", hash = "sha256:35919a9a979d7a59334b6b10e05d77c1d0d574c50e0fc98b8b1a0f165708b55a", size = 76631 } +sdist = { url = "https://files.pythonhosted.org/packages/de/ad/713be230bcda622eaa35c28f0d328c3675c371238470abdea52417f17a8e/uvicorn-0.34.3.tar.gz", hash = "sha256:35919a9a979d7a59334b6b10e05d77c1d0d574c50e0fc98b8b1a0f165708b55a", size = 76631, upload-time = "2025-06-01T07:48:17.531Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6d/0d/8adfeaa62945f90d19ddc461c55f4a50c258af7662d34b6a3d5d1f8646f6/uvicorn-0.34.3-py3-none-any.whl", hash = "sha256:16246631db62bdfbf069b0645177d6e8a77ba950cfedbfd093acef9444e4d885", size = 62431 }, + { url = "https://files.pythonhosted.org/packages/6d/0d/8adfeaa62945f90d19ddc461c55f4a50c258af7662d34b6a3d5d1f8646f6/uvicorn-0.34.3-py3-none-any.whl", hash = "sha256:16246631db62bdfbf069b0645177d6e8a77ba950cfedbfd093acef9444e4d885", size = 62431, upload-time = "2025-06-01T07:48:15.664Z" }, ] [package.optional-dependencies] @@ -1752,32 +1752,32 @@ standard = [ name = "uvloop" version = "0.21.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/c0/854216d09d33c543f12a44b393c402e89a920b1a0a7dc634c42de91b9cf6/uvloop-0.21.0.tar.gz", hash = "sha256:3bf12b0fda68447806a7ad847bfa591613177275d35b6724b1ee573faa3704e3", size = 2492741 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/76/44a55515e8c9505aa1420aebacf4dd82552e5e15691654894e90d0bd051a/uvloop-0.21.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ec7e6b09a6fdded42403182ab6b832b71f4edaf7f37a9a0e371a01db5f0cb45f", size = 1442019 }, - { url = "https://files.pythonhosted.org/packages/35/5a/62d5800358a78cc25c8a6c72ef8b10851bdb8cca22e14d9c74167b7f86da/uvloop-0.21.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:196274f2adb9689a289ad7d65700d37df0c0930fd8e4e743fa4834e850d7719d", size = 801898 }, - { url = "https://files.pythonhosted.org/packages/f3/96/63695e0ebd7da6c741ccd4489b5947394435e198a1382349c17b1146bb97/uvloop-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f38b2e090258d051d68a5b14d1da7203a3c3677321cf32a95a6f4db4dd8b6f26", size = 3827735 }, - { url = "https://files.pythonhosted.org/packages/61/e0/f0f8ec84979068ffae132c58c79af1de9cceeb664076beea86d941af1a30/uvloop-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87c43e0f13022b998eb9b973b5e97200c8b90823454d4bc06ab33829e09fb9bb", size = 3825126 }, - { url = "https://files.pythonhosted.org/packages/bf/fe/5e94a977d058a54a19df95f12f7161ab6e323ad49f4dabc28822eb2df7ea/uvloop-0.21.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:10d66943def5fcb6e7b37310eb6b5639fd2ccbc38df1177262b0640c3ca68c1f", size = 3705789 }, - { url = "https://files.pythonhosted.org/packages/26/dd/c7179618e46092a77e036650c1f056041a028a35c4d76945089fcfc38af8/uvloop-0.21.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:67dd654b8ca23aed0a8e99010b4c34aca62f4b7fce88f39d452ed7622c94845c", size = 3800523 }, - { url = "https://files.pythonhosted.org/packages/57/a7/4cf0334105c1160dd6819f3297f8700fda7fc30ab4f61fbf3e725acbc7cc/uvloop-0.21.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c0f3fa6200b3108919f8bdabb9a7f87f20e7097ea3c543754cabc7d717d95cf8", size = 1447410 }, - { url = "https://files.pythonhosted.org/packages/8c/7c/1517b0bbc2dbe784b563d6ab54f2ef88c890fdad77232c98ed490aa07132/uvloop-0.21.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0878c2640cf341b269b7e128b1a5fed890adc4455513ca710d77d5e93aa6d6a0", size = 805476 }, - { url = "https://files.pythonhosted.org/packages/ee/ea/0bfae1aceb82a503f358d8d2fa126ca9dbdb2ba9c7866974faec1cb5875c/uvloop-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9fb766bb57b7388745d8bcc53a359b116b8a04c83a2288069809d2b3466c37e", size = 3960855 }, - { url = "https://files.pythonhosted.org/packages/8a/ca/0864176a649838b838f36d44bf31c451597ab363b60dc9e09c9630619d41/uvloop-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a375441696e2eda1c43c44ccb66e04d61ceeffcd76e4929e527b7fa401b90fb", size = 3973185 }, - { url = "https://files.pythonhosted.org/packages/30/bf/08ad29979a936d63787ba47a540de2132169f140d54aa25bc8c3df3e67f4/uvloop-0.21.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:baa0e6291d91649c6ba4ed4b2f982f9fa165b5bbd50a9e203c416a2797bab3c6", size = 3820256 }, - { url = "https://files.pythonhosted.org/packages/da/e2/5cf6ef37e3daf2f06e651aae5ea108ad30df3cb269102678b61ebf1fdf42/uvloop-0.21.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4509360fcc4c3bd2c70d87573ad472de40c13387f5fda8cb58350a1d7475e58d", size = 3937323 }, - { url = "https://files.pythonhosted.org/packages/8c/4c/03f93178830dc7ce8b4cdee1d36770d2f5ebb6f3d37d354e061eefc73545/uvloop-0.21.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:359ec2c888397b9e592a889c4d72ba3d6befba8b2bb01743f72fffbde663b59c", size = 1471284 }, - { url = "https://files.pythonhosted.org/packages/43/3e/92c03f4d05e50f09251bd8b2b2b584a2a7f8fe600008bcc4523337abe676/uvloop-0.21.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f7089d2dc73179ce5ac255bdf37c236a9f914b264825fdaacaded6990a7fb4c2", size = 821349 }, - { url = "https://files.pythonhosted.org/packages/a6/ef/a02ec5da49909dbbfb1fd205a9a1ac4e88ea92dcae885e7c961847cd51e2/uvloop-0.21.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:baa4dcdbd9ae0a372f2167a207cd98c9f9a1ea1188a8a526431eef2f8116cc8d", size = 4580089 }, - { url = "https://files.pythonhosted.org/packages/06/a7/b4e6a19925c900be9f98bec0a75e6e8f79bb53bdeb891916609ab3958967/uvloop-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86975dca1c773a2c9864f4c52c5a55631038e387b47eaf56210f873887b6c8dc", size = 4693770 }, - { url = "https://files.pythonhosted.org/packages/ce/0c/f07435a18a4b94ce6bd0677d8319cd3de61f3a9eeb1e5f8ab4e8b5edfcb3/uvloop-0.21.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:461d9ae6660fbbafedd07559c6a2e57cd553b34b0065b6550685f6653a98c1cb", size = 4451321 }, - { url = "https://files.pythonhosted.org/packages/8f/eb/f7032be105877bcf924709c97b1bf3b90255b4ec251f9340cef912559f28/uvloop-0.21.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:183aef7c8730e54c9a3ee3227464daed66e37ba13040bb3f350bc2ddc040f22f", size = 4659022 }, - { url = "https://files.pythonhosted.org/packages/3f/8d/2cbef610ca21539f0f36e2b34da49302029e7c9f09acef0b1c3b5839412b/uvloop-0.21.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bfd55dfcc2a512316e65f16e503e9e450cab148ef11df4e4e679b5e8253a5281", size = 1468123 }, - { url = "https://files.pythonhosted.org/packages/93/0d/b0038d5a469f94ed8f2b2fce2434a18396d8fbfb5da85a0a9781ebbdec14/uvloop-0.21.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:787ae31ad8a2856fc4e7c095341cccc7209bd657d0e71ad0dc2ea83c4a6fa8af", size = 819325 }, - { url = "https://files.pythonhosted.org/packages/50/94/0a687f39e78c4c1e02e3272c6b2ccdb4e0085fda3b8352fecd0410ccf915/uvloop-0.21.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ee4d4ef48036ff6e5cfffb09dd192c7a5027153948d85b8da7ff705065bacc6", size = 4582806 }, - { url = "https://files.pythonhosted.org/packages/d2/19/f5b78616566ea68edd42aacaf645adbf71fbd83fc52281fba555dc27e3f1/uvloop-0.21.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3df876acd7ec037a3d005b3ab85a7e4110422e4d9c1571d4fc89b0fc41b6816", size = 4701068 }, - { url = "https://files.pythonhosted.org/packages/47/57/66f061ee118f413cd22a656de622925097170b9380b30091b78ea0c6ea75/uvloop-0.21.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd53ecc9a0f3d87ab847503c2e1552b690362e005ab54e8a48ba97da3924c0dc", size = 4454428 }, - { url = "https://files.pythonhosted.org/packages/63/9a/0962b05b308494e3202d3f794a6e85abe471fe3cafdbcf95c2e8c713aabd/uvloop-0.21.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a5c39f217ab3c663dc699c04cbd50c13813e31d917642d459fdcec07555cc553", size = 4660018 }, +sdist = { url = "https://files.pythonhosted.org/packages/af/c0/854216d09d33c543f12a44b393c402e89a920b1a0a7dc634c42de91b9cf6/uvloop-0.21.0.tar.gz", hash = "sha256:3bf12b0fda68447806a7ad847bfa591613177275d35b6724b1ee573faa3704e3", size = 2492741, upload-time = "2024-10-14T23:38:35.489Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/76/44a55515e8c9505aa1420aebacf4dd82552e5e15691654894e90d0bd051a/uvloop-0.21.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ec7e6b09a6fdded42403182ab6b832b71f4edaf7f37a9a0e371a01db5f0cb45f", size = 1442019, upload-time = "2024-10-14T23:37:20.068Z" }, + { url = "https://files.pythonhosted.org/packages/35/5a/62d5800358a78cc25c8a6c72ef8b10851bdb8cca22e14d9c74167b7f86da/uvloop-0.21.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:196274f2adb9689a289ad7d65700d37df0c0930fd8e4e743fa4834e850d7719d", size = 801898, upload-time = "2024-10-14T23:37:22.663Z" }, + { url = "https://files.pythonhosted.org/packages/f3/96/63695e0ebd7da6c741ccd4489b5947394435e198a1382349c17b1146bb97/uvloop-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f38b2e090258d051d68a5b14d1da7203a3c3677321cf32a95a6f4db4dd8b6f26", size = 3827735, upload-time = "2024-10-14T23:37:25.129Z" }, + { url = "https://files.pythonhosted.org/packages/61/e0/f0f8ec84979068ffae132c58c79af1de9cceeb664076beea86d941af1a30/uvloop-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87c43e0f13022b998eb9b973b5e97200c8b90823454d4bc06ab33829e09fb9bb", size = 3825126, upload-time = "2024-10-14T23:37:27.59Z" }, + { url = "https://files.pythonhosted.org/packages/bf/fe/5e94a977d058a54a19df95f12f7161ab6e323ad49f4dabc28822eb2df7ea/uvloop-0.21.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:10d66943def5fcb6e7b37310eb6b5639fd2ccbc38df1177262b0640c3ca68c1f", size = 3705789, upload-time = "2024-10-14T23:37:29.385Z" }, + { url = "https://files.pythonhosted.org/packages/26/dd/c7179618e46092a77e036650c1f056041a028a35c4d76945089fcfc38af8/uvloop-0.21.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:67dd654b8ca23aed0a8e99010b4c34aca62f4b7fce88f39d452ed7622c94845c", size = 3800523, upload-time = "2024-10-14T23:37:32.048Z" }, + { url = "https://files.pythonhosted.org/packages/57/a7/4cf0334105c1160dd6819f3297f8700fda7fc30ab4f61fbf3e725acbc7cc/uvloop-0.21.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c0f3fa6200b3108919f8bdabb9a7f87f20e7097ea3c543754cabc7d717d95cf8", size = 1447410, upload-time = "2024-10-14T23:37:33.612Z" }, + { url = "https://files.pythonhosted.org/packages/8c/7c/1517b0bbc2dbe784b563d6ab54f2ef88c890fdad77232c98ed490aa07132/uvloop-0.21.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0878c2640cf341b269b7e128b1a5fed890adc4455513ca710d77d5e93aa6d6a0", size = 805476, upload-time = "2024-10-14T23:37:36.11Z" }, + { url = "https://files.pythonhosted.org/packages/ee/ea/0bfae1aceb82a503f358d8d2fa126ca9dbdb2ba9c7866974faec1cb5875c/uvloop-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9fb766bb57b7388745d8bcc53a359b116b8a04c83a2288069809d2b3466c37e", size = 3960855, upload-time = "2024-10-14T23:37:37.683Z" }, + { url = "https://files.pythonhosted.org/packages/8a/ca/0864176a649838b838f36d44bf31c451597ab363b60dc9e09c9630619d41/uvloop-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a375441696e2eda1c43c44ccb66e04d61ceeffcd76e4929e527b7fa401b90fb", size = 3973185, upload-time = "2024-10-14T23:37:40.226Z" }, + { url = "https://files.pythonhosted.org/packages/30/bf/08ad29979a936d63787ba47a540de2132169f140d54aa25bc8c3df3e67f4/uvloop-0.21.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:baa0e6291d91649c6ba4ed4b2f982f9fa165b5bbd50a9e203c416a2797bab3c6", size = 3820256, upload-time = "2024-10-14T23:37:42.839Z" }, + { url = "https://files.pythonhosted.org/packages/da/e2/5cf6ef37e3daf2f06e651aae5ea108ad30df3cb269102678b61ebf1fdf42/uvloop-0.21.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4509360fcc4c3bd2c70d87573ad472de40c13387f5fda8cb58350a1d7475e58d", size = 3937323, upload-time = "2024-10-14T23:37:45.337Z" }, + { url = "https://files.pythonhosted.org/packages/8c/4c/03f93178830dc7ce8b4cdee1d36770d2f5ebb6f3d37d354e061eefc73545/uvloop-0.21.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:359ec2c888397b9e592a889c4d72ba3d6befba8b2bb01743f72fffbde663b59c", size = 1471284, upload-time = "2024-10-14T23:37:47.833Z" }, + { url = "https://files.pythonhosted.org/packages/43/3e/92c03f4d05e50f09251bd8b2b2b584a2a7f8fe600008bcc4523337abe676/uvloop-0.21.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f7089d2dc73179ce5ac255bdf37c236a9f914b264825fdaacaded6990a7fb4c2", size = 821349, upload-time = "2024-10-14T23:37:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/a6/ef/a02ec5da49909dbbfb1fd205a9a1ac4e88ea92dcae885e7c961847cd51e2/uvloop-0.21.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:baa4dcdbd9ae0a372f2167a207cd98c9f9a1ea1188a8a526431eef2f8116cc8d", size = 4580089, upload-time = "2024-10-14T23:37:51.703Z" }, + { url = "https://files.pythonhosted.org/packages/06/a7/b4e6a19925c900be9f98bec0a75e6e8f79bb53bdeb891916609ab3958967/uvloop-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86975dca1c773a2c9864f4c52c5a55631038e387b47eaf56210f873887b6c8dc", size = 4693770, upload-time = "2024-10-14T23:37:54.122Z" }, + { url = "https://files.pythonhosted.org/packages/ce/0c/f07435a18a4b94ce6bd0677d8319cd3de61f3a9eeb1e5f8ab4e8b5edfcb3/uvloop-0.21.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:461d9ae6660fbbafedd07559c6a2e57cd553b34b0065b6550685f6653a98c1cb", size = 4451321, upload-time = "2024-10-14T23:37:55.766Z" }, + { url = "https://files.pythonhosted.org/packages/8f/eb/f7032be105877bcf924709c97b1bf3b90255b4ec251f9340cef912559f28/uvloop-0.21.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:183aef7c8730e54c9a3ee3227464daed66e37ba13040bb3f350bc2ddc040f22f", size = 4659022, upload-time = "2024-10-14T23:37:58.195Z" }, + { url = "https://files.pythonhosted.org/packages/3f/8d/2cbef610ca21539f0f36e2b34da49302029e7c9f09acef0b1c3b5839412b/uvloop-0.21.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bfd55dfcc2a512316e65f16e503e9e450cab148ef11df4e4e679b5e8253a5281", size = 1468123, upload-time = "2024-10-14T23:38:00.688Z" }, + { url = "https://files.pythonhosted.org/packages/93/0d/b0038d5a469f94ed8f2b2fce2434a18396d8fbfb5da85a0a9781ebbdec14/uvloop-0.21.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:787ae31ad8a2856fc4e7c095341cccc7209bd657d0e71ad0dc2ea83c4a6fa8af", size = 819325, upload-time = "2024-10-14T23:38:02.309Z" }, + { url = "https://files.pythonhosted.org/packages/50/94/0a687f39e78c4c1e02e3272c6b2ccdb4e0085fda3b8352fecd0410ccf915/uvloop-0.21.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ee4d4ef48036ff6e5cfffb09dd192c7a5027153948d85b8da7ff705065bacc6", size = 4582806, upload-time = "2024-10-14T23:38:04.711Z" }, + { url = "https://files.pythonhosted.org/packages/d2/19/f5b78616566ea68edd42aacaf645adbf71fbd83fc52281fba555dc27e3f1/uvloop-0.21.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3df876acd7ec037a3d005b3ab85a7e4110422e4d9c1571d4fc89b0fc41b6816", size = 4701068, upload-time = "2024-10-14T23:38:06.385Z" }, + { url = "https://files.pythonhosted.org/packages/47/57/66f061ee118f413cd22a656de622925097170b9380b30091b78ea0c6ea75/uvloop-0.21.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd53ecc9a0f3d87ab847503c2e1552b690362e005ab54e8a48ba97da3924c0dc", size = 4454428, upload-time = "2024-10-14T23:38:08.416Z" }, + { url = "https://files.pythonhosted.org/packages/63/9a/0962b05b308494e3202d3f794a6e85abe471fe3cafdbcf95c2e8c713aabd/uvloop-0.21.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a5c39f217ab3c663dc699c04cbd50c13813e31d917642d459fdcec07555cc553", size = 4660018, upload-time = "2024-10-14T23:38:10.888Z" }, ] [[package]] @@ -1787,62 +1787,62 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/03/e2/8ed598c42057de7aa5d97c472254af4906ff0a59a66699d426fc9ef795d7/watchfiles-1.0.5.tar.gz", hash = "sha256:b7529b5dcc114679d43827d8c35a07c493ad6f083633d573d81c660abc5979e9", size = 94537 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/af/4d/d02e6ea147bb7fff5fd109c694a95109612f419abed46548a930e7f7afa3/watchfiles-1.0.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:5c40fe7dd9e5f81e0847b1ea64e1f5dd79dd61afbedb57759df06767ac719b40", size = 405632 }, - { url = "https://files.pythonhosted.org/packages/60/31/9ee50e29129d53a9a92ccf1d3992751dc56fc3c8f6ee721be1c7b9c81763/watchfiles-1.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8c0db396e6003d99bb2d7232c957b5f0b5634bbd1b24e381a5afcc880f7373fb", size = 395734 }, - { url = "https://files.pythonhosted.org/packages/ad/8c/759176c97195306f028024f878e7f1c776bda66ccc5c68fa51e699cf8f1d/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b551d4fb482fc57d852b4541f911ba28957d051c8776e79c3b4a51eb5e2a1b11", size = 455008 }, - { url = "https://files.pythonhosted.org/packages/55/1a/5e977250c795ee79a0229e3b7f5e3a1b664e4e450756a22da84d2f4979fe/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:830aa432ba5c491d52a15b51526c29e4a4b92bf4f92253787f9726fe01519487", size = 459029 }, - { url = "https://files.pythonhosted.org/packages/e6/17/884cf039333605c1d6e296cf5be35fad0836953c3dfd2adb71b72f9dbcd0/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a16512051a822a416b0d477d5f8c0e67b67c1a20d9acecb0aafa3aa4d6e7d256", size = 488916 }, - { url = "https://files.pythonhosted.org/packages/ef/e0/bcb6e64b45837056c0a40f3a2db3ef51c2ced19fda38484fa7508e00632c/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe0cbc787770e52a96c6fda6726ace75be7f840cb327e1b08d7d54eadc3bc85", size = 523763 }, - { url = "https://files.pythonhosted.org/packages/24/e9/f67e9199f3bb35c1837447ecf07e9830ec00ff5d35a61e08c2cd67217949/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d363152c5e16b29d66cbde8fa614f9e313e6f94a8204eaab268db52231fe5358", size = 502891 }, - { url = "https://files.pythonhosted.org/packages/23/ed/a6cf815f215632f5c8065e9c41fe872025ffea35aa1f80499f86eae922db/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ee32c9a9bee4d0b7bd7cbeb53cb185cf0b622ac761efaa2eba84006c3b3a614", size = 454921 }, - { url = "https://files.pythonhosted.org/packages/92/4c/e14978599b80cde8486ab5a77a821e8a982ae8e2fcb22af7b0886a033ec8/watchfiles-1.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:29c7fd632ccaf5517c16a5188e36f6612d6472ccf55382db6c7fe3fcccb7f59f", size = 631422 }, - { url = "https://files.pythonhosted.org/packages/b2/1a/9263e34c3458f7614b657f974f4ee61fd72f58adce8b436e16450e054efd/watchfiles-1.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e637810586e6fe380c8bc1b3910accd7f1d3a9a7262c8a78d4c8fb3ba6a2b3d", size = 625675 }, - { url = "https://files.pythonhosted.org/packages/96/1f/1803a18bd6ab04a0766386a19bcfe64641381a04939efdaa95f0e3b0eb58/watchfiles-1.0.5-cp310-cp310-win32.whl", hash = "sha256:cd47d063fbeabd4c6cae1d4bcaa38f0902f8dc5ed168072874ea11d0c7afc1ff", size = 277921 }, - { url = "https://files.pythonhosted.org/packages/c2/3b/29a89de074a7d6e8b4dc67c26e03d73313e4ecf0d6e97e942a65fa7c195e/watchfiles-1.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:86c0df05b47a79d80351cd179893f2f9c1b1cae49d96e8b3290c7f4bd0ca0a92", size = 291526 }, - { url = "https://files.pythonhosted.org/packages/39/f4/41b591f59021786ef517e1cdc3b510383551846703e03f204827854a96f8/watchfiles-1.0.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:237f9be419e977a0f8f6b2e7b0475ababe78ff1ab06822df95d914a945eac827", size = 405336 }, - { url = "https://files.pythonhosted.org/packages/ae/06/93789c135be4d6d0e4f63e96eea56dc54050b243eacc28439a26482b5235/watchfiles-1.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0da39ff917af8b27a4bdc5a97ac577552a38aac0d260a859c1517ea3dc1a7c4", size = 395977 }, - { url = "https://files.pythonhosted.org/packages/d2/db/1cd89bd83728ca37054512d4d35ab69b5f12b8aa2ac9be3b0276b3bf06cc/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cfcb3952350e95603f232a7a15f6c5f86c5375e46f0bd4ae70d43e3e063c13d", size = 455232 }, - { url = "https://files.pythonhosted.org/packages/40/90/d8a4d44ffe960517e487c9c04f77b06b8abf05eb680bed71c82b5f2cad62/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b2dddba7a4e6151384e252a5632efcaa9bc5d1c4b567f3cb621306b2ca9f63", size = 459151 }, - { url = "https://files.pythonhosted.org/packages/6c/da/267a1546f26465dead1719caaba3ce660657f83c9d9c052ba98fb8856e13/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:95cf944fcfc394c5f9de794ce581914900f82ff1f855326f25ebcf24d5397418", size = 489054 }, - { url = "https://files.pythonhosted.org/packages/b1/31/33850dfd5c6efb6f27d2465cc4c6b27c5a6f5ed53c6fa63b7263cf5f60f6/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ecf6cd9f83d7c023b1aba15d13f705ca7b7d38675c121f3cc4a6e25bd0857ee9", size = 523955 }, - { url = "https://files.pythonhosted.org/packages/09/84/b7d7b67856efb183a421f1416b44ca975cb2ea6c4544827955dfb01f7dc2/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:852de68acd6212cd6d33edf21e6f9e56e5d98c6add46f48244bd479d97c967c6", size = 502234 }, - { url = "https://files.pythonhosted.org/packages/71/87/6dc5ec6882a2254cfdd8b0718b684504e737273903b65d7338efaba08b52/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5730f3aa35e646103b53389d5bc77edfbf578ab6dab2e005142b5b80a35ef25", size = 454750 }, - { url = "https://files.pythonhosted.org/packages/3d/6c/3786c50213451a0ad15170d091570d4a6554976cf0df19878002fc96075a/watchfiles-1.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:18b3bd29954bc4abeeb4e9d9cf0b30227f0f206c86657674f544cb032296acd5", size = 631591 }, - { url = "https://files.pythonhosted.org/packages/1b/b3/1427425ade4e359a0deacce01a47a26024b2ccdb53098f9d64d497f6684c/watchfiles-1.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ba5552a1b07c8edbf197055bc9d518b8f0d98a1c6a73a293bc0726dce068ed01", size = 625370 }, - { url = "https://files.pythonhosted.org/packages/15/ba/f60e053b0b5b8145d682672024aa91370a29c5c921a88977eb565de34086/watchfiles-1.0.5-cp311-cp311-win32.whl", hash = "sha256:2f1fefb2e90e89959447bc0420fddd1e76f625784340d64a2f7d5983ef9ad246", size = 277791 }, - { url = "https://files.pythonhosted.org/packages/50/ed/7603c4e164225c12c0d4e8700b64bb00e01a6c4eeea372292a3856be33a4/watchfiles-1.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:b6e76ceb1dd18c8e29c73f47d41866972e891fc4cc7ba014f487def72c1cf096", size = 291622 }, - { url = "https://files.pythonhosted.org/packages/a2/c2/99bb7c96b4450e36877fde33690ded286ff555b5a5c1d925855d556968a1/watchfiles-1.0.5-cp311-cp311-win_arm64.whl", hash = "sha256:266710eb6fddc1f5e51843c70e3bebfb0f5e77cf4f27129278c70554104d19ed", size = 283699 }, - { url = "https://files.pythonhosted.org/packages/2a/8c/4f0b9bdb75a1bfbd9c78fad7d8854369283f74fe7cf03eb16be77054536d/watchfiles-1.0.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b5eb568c2aa6018e26da9e6c86f3ec3fd958cee7f0311b35c2630fa4217d17f2", size = 401511 }, - { url = "https://files.pythonhosted.org/packages/dc/4e/7e15825def77f8bd359b6d3f379f0c9dac4eb09dd4ddd58fd7d14127179c/watchfiles-1.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0a04059f4923ce4e856b4b4e5e783a70f49d9663d22a4c3b3298165996d1377f", size = 392715 }, - { url = "https://files.pythonhosted.org/packages/58/65/b72fb817518728e08de5840d5d38571466c1b4a3f724d190cec909ee6f3f/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e380c89983ce6e6fe2dd1e1921b9952fb4e6da882931abd1824c092ed495dec", size = 454138 }, - { url = "https://files.pythonhosted.org/packages/3e/a4/86833fd2ea2e50ae28989f5950b5c3f91022d67092bfec08f8300d8b347b/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fe43139b2c0fdc4a14d4f8d5b5d967f7a2777fd3d38ecf5b1ec669b0d7e43c21", size = 458592 }, - { url = "https://files.pythonhosted.org/packages/38/7e/42cb8df8be9a37e50dd3a818816501cf7a20d635d76d6bd65aae3dbbff68/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee0822ce1b8a14fe5a066f93edd20aada932acfe348bede8aa2149f1a4489512", size = 487532 }, - { url = "https://files.pythonhosted.org/packages/fc/fd/13d26721c85d7f3df6169d8b495fcac8ab0dc8f0945ebea8845de4681dab/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a0dbcb1c2d8f2ab6e0a81c6699b236932bd264d4cef1ac475858d16c403de74d", size = 522865 }, - { url = "https://files.pythonhosted.org/packages/a1/0d/7f9ae243c04e96c5455d111e21b09087d0eeaf9a1369e13a01c7d3d82478/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a2014a2b18ad3ca53b1f6c23f8cd94a18ce930c1837bd891262c182640eb40a6", size = 499887 }, - { url = "https://files.pythonhosted.org/packages/8e/0f/a257766998e26aca4b3acf2ae97dff04b57071e991a510857d3799247c67/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f6ae86d5cb647bf58f9f655fcf577f713915a5d69057a0371bc257e2553234", size = 454498 }, - { url = "https://files.pythonhosted.org/packages/81/79/8bf142575a03e0af9c3d5f8bcae911ee6683ae93a625d349d4ecf4c8f7df/watchfiles-1.0.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1a7bac2bde1d661fb31f4d4e8e539e178774b76db3c2c17c4bb3e960a5de07a2", size = 630663 }, - { url = "https://files.pythonhosted.org/packages/f1/80/abe2e79f610e45c63a70d271caea90c49bbf93eb00fa947fa9b803a1d51f/watchfiles-1.0.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ab626da2fc1ac277bbf752446470b367f84b50295264d2d313e28dc4405d663", size = 625410 }, - { url = "https://files.pythonhosted.org/packages/91/6f/bc7fbecb84a41a9069c2c6eb6319f7f7df113adf113e358c57fc1aff7ff5/watchfiles-1.0.5-cp312-cp312-win32.whl", hash = "sha256:9f4571a783914feda92018ef3901dab8caf5b029325b5fe4558c074582815249", size = 277965 }, - { url = "https://files.pythonhosted.org/packages/99/a5/bf1c297ea6649ec59e935ab311f63d8af5faa8f0b86993e3282b984263e3/watchfiles-1.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:360a398c3a19672cf93527f7e8d8b60d8275119c5d900f2e184d32483117a705", size = 291693 }, - { url = "https://files.pythonhosted.org/packages/7f/7b/fd01087cc21db5c47e5beae507b87965db341cce8a86f9eb12bf5219d4e0/watchfiles-1.0.5-cp312-cp312-win_arm64.whl", hash = "sha256:1a2902ede862969077b97523987c38db28abbe09fb19866e711485d9fbf0d417", size = 283287 }, - { url = "https://files.pythonhosted.org/packages/c7/62/435766874b704f39b2fecd8395a29042db2b5ec4005bd34523415e9bd2e0/watchfiles-1.0.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0b289572c33a0deae62daa57e44a25b99b783e5f7aed81b314232b3d3c81a11d", size = 401531 }, - { url = "https://files.pythonhosted.org/packages/6e/a6/e52a02c05411b9cb02823e6797ef9bbba0bfaf1bb627da1634d44d8af833/watchfiles-1.0.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a056c2f692d65bf1e99c41045e3bdcaea3cb9e6b5a53dcaf60a5f3bd95fc9763", size = 392417 }, - { url = "https://files.pythonhosted.org/packages/3f/53/c4af6819770455932144e0109d4854437769672d7ad897e76e8e1673435d/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9dca99744991fc9850d18015c4f0438865414e50069670f5f7eee08340d8b40", size = 453423 }, - { url = "https://files.pythonhosted.org/packages/cb/d1/8e88df58bbbf819b8bc5cfbacd3c79e01b40261cad0fc84d1e1ebd778a07/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:894342d61d355446d02cd3988a7326af344143eb33a2fd5d38482a92072d9563", size = 458185 }, - { url = "https://files.pythonhosted.org/packages/ff/70/fffaa11962dd5429e47e478a18736d4e42bec42404f5ee3b92ef1b87ad60/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab44e1580924d1ffd7b3938e02716d5ad190441965138b4aa1d1f31ea0877f04", size = 486696 }, - { url = "https://files.pythonhosted.org/packages/39/db/723c0328e8b3692d53eb273797d9a08be6ffb1d16f1c0ba2bdbdc2a3852c/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d6f9367b132078b2ceb8d066ff6c93a970a18c3029cea37bfd7b2d3dd2e5db8f", size = 522327 }, - { url = "https://files.pythonhosted.org/packages/cd/05/9fccc43c50c39a76b68343484b9da7b12d42d0859c37c61aec018c967a32/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2e55a9b162e06e3f862fb61e399fe9f05d908d019d87bf5b496a04ef18a970a", size = 499741 }, - { url = "https://files.pythonhosted.org/packages/23/14/499e90c37fa518976782b10a18b18db9f55ea73ca14641615056f8194bb3/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0125f91f70e0732a9f8ee01e49515c35d38ba48db507a50c5bdcad9503af5827", size = 453995 }, - { url = "https://files.pythonhosted.org/packages/61/d9/f75d6840059320df5adecd2c687fbc18960a7f97b55c300d20f207d48aef/watchfiles-1.0.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:13bb21f8ba3248386337c9fa51c528868e6c34a707f729ab041c846d52a0c69a", size = 629693 }, - { url = "https://files.pythonhosted.org/packages/fc/17/180ca383f5061b61406477218c55d66ec118e6c0c51f02d8142895fcf0a9/watchfiles-1.0.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:839ebd0df4a18c5b3c1b890145b5a3f5f64063c2a0d02b13c76d78fe5de34936", size = 624677 }, - { url = "https://files.pythonhosted.org/packages/bf/15/714d6ef307f803f236d69ee9d421763707899d6298d9f3183e55e366d9af/watchfiles-1.0.5-cp313-cp313-win32.whl", hash = "sha256:4a8ec1e4e16e2d5bafc9ba82f7aaecfeec990ca7cd27e84fb6f191804ed2fcfc", size = 277804 }, - { url = "https://files.pythonhosted.org/packages/a8/b4/c57b99518fadf431f3ef47a610839e46e5f8abf9814f969859d1c65c02c7/watchfiles-1.0.5-cp313-cp313-win_amd64.whl", hash = "sha256:f436601594f15bf406518af922a89dcaab416568edb6f65c4e5bbbad1ea45c11", size = 291087 }, - { url = "https://files.pythonhosted.org/packages/1a/03/81f9fcc3963b3fc415cd4b0b2b39ee8cc136c42fb10a36acf38745e9d283/watchfiles-1.0.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f59b870db1f1ae5a9ac28245707d955c8721dd6565e7f411024fa374b5362d1d", size = 405947 }, - { url = "https://files.pythonhosted.org/packages/54/97/8c4213a852feb64807ec1d380f42d4fc8bfaef896bdbd94318f8fd7f3e4e/watchfiles-1.0.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9475b0093767e1475095f2aeb1d219fb9664081d403d1dff81342df8cd707034", size = 397276 }, - { url = "https://files.pythonhosted.org/packages/78/12/d4464d19860cb9672efa45eec1b08f8472c478ed67dcd30647c51ada7aef/watchfiles-1.0.5-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc533aa50664ebd6c628b2f30591956519462f5d27f951ed03d6c82b2dfd9965", size = 455550 }, - { url = "https://files.pythonhosted.org/packages/90/fb/b07bcdf1034d8edeaef4c22f3e9e3157d37c5071b5f9492ffdfa4ad4bed7/watchfiles-1.0.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed1cd825158dcaae36acce7b2db33dcbfd12b30c34317a88b8ed80f0541cc57", size = 455542 }, +sdist = { url = "https://files.pythonhosted.org/packages/03/e2/8ed598c42057de7aa5d97c472254af4906ff0a59a66699d426fc9ef795d7/watchfiles-1.0.5.tar.gz", hash = "sha256:b7529b5dcc114679d43827d8c35a07c493ad6f083633d573d81c660abc5979e9", size = 94537, upload-time = "2025-04-08T10:36:26.722Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/4d/d02e6ea147bb7fff5fd109c694a95109612f419abed46548a930e7f7afa3/watchfiles-1.0.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:5c40fe7dd9e5f81e0847b1ea64e1f5dd79dd61afbedb57759df06767ac719b40", size = 405632, upload-time = "2025-04-08T10:34:41.832Z" }, + { url = "https://files.pythonhosted.org/packages/60/31/9ee50e29129d53a9a92ccf1d3992751dc56fc3c8f6ee721be1c7b9c81763/watchfiles-1.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8c0db396e6003d99bb2d7232c957b5f0b5634bbd1b24e381a5afcc880f7373fb", size = 395734, upload-time = "2025-04-08T10:34:44.236Z" }, + { url = "https://files.pythonhosted.org/packages/ad/8c/759176c97195306f028024f878e7f1c776bda66ccc5c68fa51e699cf8f1d/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b551d4fb482fc57d852b4541f911ba28957d051c8776e79c3b4a51eb5e2a1b11", size = 455008, upload-time = "2025-04-08T10:34:45.617Z" }, + { url = "https://files.pythonhosted.org/packages/55/1a/5e977250c795ee79a0229e3b7f5e3a1b664e4e450756a22da84d2f4979fe/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:830aa432ba5c491d52a15b51526c29e4a4b92bf4f92253787f9726fe01519487", size = 459029, upload-time = "2025-04-08T10:34:46.814Z" }, + { url = "https://files.pythonhosted.org/packages/e6/17/884cf039333605c1d6e296cf5be35fad0836953c3dfd2adb71b72f9dbcd0/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a16512051a822a416b0d477d5f8c0e67b67c1a20d9acecb0aafa3aa4d6e7d256", size = 488916, upload-time = "2025-04-08T10:34:48.571Z" }, + { url = "https://files.pythonhosted.org/packages/ef/e0/bcb6e64b45837056c0a40f3a2db3ef51c2ced19fda38484fa7508e00632c/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe0cbc787770e52a96c6fda6726ace75be7f840cb327e1b08d7d54eadc3bc85", size = 523763, upload-time = "2025-04-08T10:34:50.268Z" }, + { url = "https://files.pythonhosted.org/packages/24/e9/f67e9199f3bb35c1837447ecf07e9830ec00ff5d35a61e08c2cd67217949/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d363152c5e16b29d66cbde8fa614f9e313e6f94a8204eaab268db52231fe5358", size = 502891, upload-time = "2025-04-08T10:34:51.419Z" }, + { url = "https://files.pythonhosted.org/packages/23/ed/a6cf815f215632f5c8065e9c41fe872025ffea35aa1f80499f86eae922db/watchfiles-1.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ee32c9a9bee4d0b7bd7cbeb53cb185cf0b622ac761efaa2eba84006c3b3a614", size = 454921, upload-time = "2025-04-08T10:34:52.67Z" }, + { url = "https://files.pythonhosted.org/packages/92/4c/e14978599b80cde8486ab5a77a821e8a982ae8e2fcb22af7b0886a033ec8/watchfiles-1.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:29c7fd632ccaf5517c16a5188e36f6612d6472ccf55382db6c7fe3fcccb7f59f", size = 631422, upload-time = "2025-04-08T10:34:53.985Z" }, + { url = "https://files.pythonhosted.org/packages/b2/1a/9263e34c3458f7614b657f974f4ee61fd72f58adce8b436e16450e054efd/watchfiles-1.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e637810586e6fe380c8bc1b3910accd7f1d3a9a7262c8a78d4c8fb3ba6a2b3d", size = 625675, upload-time = "2025-04-08T10:34:55.173Z" }, + { url = "https://files.pythonhosted.org/packages/96/1f/1803a18bd6ab04a0766386a19bcfe64641381a04939efdaa95f0e3b0eb58/watchfiles-1.0.5-cp310-cp310-win32.whl", hash = "sha256:cd47d063fbeabd4c6cae1d4bcaa38f0902f8dc5ed168072874ea11d0c7afc1ff", size = 277921, upload-time = "2025-04-08T10:34:56.318Z" }, + { url = "https://files.pythonhosted.org/packages/c2/3b/29a89de074a7d6e8b4dc67c26e03d73313e4ecf0d6e97e942a65fa7c195e/watchfiles-1.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:86c0df05b47a79d80351cd179893f2f9c1b1cae49d96e8b3290c7f4bd0ca0a92", size = 291526, upload-time = "2025-04-08T10:34:57.95Z" }, + { url = "https://files.pythonhosted.org/packages/39/f4/41b591f59021786ef517e1cdc3b510383551846703e03f204827854a96f8/watchfiles-1.0.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:237f9be419e977a0f8f6b2e7b0475ababe78ff1ab06822df95d914a945eac827", size = 405336, upload-time = "2025-04-08T10:34:59.359Z" }, + { url = "https://files.pythonhosted.org/packages/ae/06/93789c135be4d6d0e4f63e96eea56dc54050b243eacc28439a26482b5235/watchfiles-1.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0da39ff917af8b27a4bdc5a97ac577552a38aac0d260a859c1517ea3dc1a7c4", size = 395977, upload-time = "2025-04-08T10:35:00.522Z" }, + { url = "https://files.pythonhosted.org/packages/d2/db/1cd89bd83728ca37054512d4d35ab69b5f12b8aa2ac9be3b0276b3bf06cc/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cfcb3952350e95603f232a7a15f6c5f86c5375e46f0bd4ae70d43e3e063c13d", size = 455232, upload-time = "2025-04-08T10:35:01.698Z" }, + { url = "https://files.pythonhosted.org/packages/40/90/d8a4d44ffe960517e487c9c04f77b06b8abf05eb680bed71c82b5f2cad62/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b2dddba7a4e6151384e252a5632efcaa9bc5d1c4b567f3cb621306b2ca9f63", size = 459151, upload-time = "2025-04-08T10:35:03.358Z" }, + { url = "https://files.pythonhosted.org/packages/6c/da/267a1546f26465dead1719caaba3ce660657f83c9d9c052ba98fb8856e13/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:95cf944fcfc394c5f9de794ce581914900f82ff1f855326f25ebcf24d5397418", size = 489054, upload-time = "2025-04-08T10:35:04.561Z" }, + { url = "https://files.pythonhosted.org/packages/b1/31/33850dfd5c6efb6f27d2465cc4c6b27c5a6f5ed53c6fa63b7263cf5f60f6/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ecf6cd9f83d7c023b1aba15d13f705ca7b7d38675c121f3cc4a6e25bd0857ee9", size = 523955, upload-time = "2025-04-08T10:35:05.786Z" }, + { url = "https://files.pythonhosted.org/packages/09/84/b7d7b67856efb183a421f1416b44ca975cb2ea6c4544827955dfb01f7dc2/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:852de68acd6212cd6d33edf21e6f9e56e5d98c6add46f48244bd479d97c967c6", size = 502234, upload-time = "2025-04-08T10:35:07.187Z" }, + { url = "https://files.pythonhosted.org/packages/71/87/6dc5ec6882a2254cfdd8b0718b684504e737273903b65d7338efaba08b52/watchfiles-1.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5730f3aa35e646103b53389d5bc77edfbf578ab6dab2e005142b5b80a35ef25", size = 454750, upload-time = "2025-04-08T10:35:08.859Z" }, + { url = "https://files.pythonhosted.org/packages/3d/6c/3786c50213451a0ad15170d091570d4a6554976cf0df19878002fc96075a/watchfiles-1.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:18b3bd29954bc4abeeb4e9d9cf0b30227f0f206c86657674f544cb032296acd5", size = 631591, upload-time = "2025-04-08T10:35:10.64Z" }, + { url = "https://files.pythonhosted.org/packages/1b/b3/1427425ade4e359a0deacce01a47a26024b2ccdb53098f9d64d497f6684c/watchfiles-1.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ba5552a1b07c8edbf197055bc9d518b8f0d98a1c6a73a293bc0726dce068ed01", size = 625370, upload-time = "2025-04-08T10:35:12.412Z" }, + { url = "https://files.pythonhosted.org/packages/15/ba/f60e053b0b5b8145d682672024aa91370a29c5c921a88977eb565de34086/watchfiles-1.0.5-cp311-cp311-win32.whl", hash = "sha256:2f1fefb2e90e89959447bc0420fddd1e76f625784340d64a2f7d5983ef9ad246", size = 277791, upload-time = "2025-04-08T10:35:13.719Z" }, + { url = "https://files.pythonhosted.org/packages/50/ed/7603c4e164225c12c0d4e8700b64bb00e01a6c4eeea372292a3856be33a4/watchfiles-1.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:b6e76ceb1dd18c8e29c73f47d41866972e891fc4cc7ba014f487def72c1cf096", size = 291622, upload-time = "2025-04-08T10:35:15.071Z" }, + { url = "https://files.pythonhosted.org/packages/a2/c2/99bb7c96b4450e36877fde33690ded286ff555b5a5c1d925855d556968a1/watchfiles-1.0.5-cp311-cp311-win_arm64.whl", hash = "sha256:266710eb6fddc1f5e51843c70e3bebfb0f5e77cf4f27129278c70554104d19ed", size = 283699, upload-time = "2025-04-08T10:35:16.732Z" }, + { url = "https://files.pythonhosted.org/packages/2a/8c/4f0b9bdb75a1bfbd9c78fad7d8854369283f74fe7cf03eb16be77054536d/watchfiles-1.0.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b5eb568c2aa6018e26da9e6c86f3ec3fd958cee7f0311b35c2630fa4217d17f2", size = 401511, upload-time = "2025-04-08T10:35:17.956Z" }, + { url = "https://files.pythonhosted.org/packages/dc/4e/7e15825def77f8bd359b6d3f379f0c9dac4eb09dd4ddd58fd7d14127179c/watchfiles-1.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0a04059f4923ce4e856b4b4e5e783a70f49d9663d22a4c3b3298165996d1377f", size = 392715, upload-time = "2025-04-08T10:35:19.202Z" }, + { url = "https://files.pythonhosted.org/packages/58/65/b72fb817518728e08de5840d5d38571466c1b4a3f724d190cec909ee6f3f/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e380c89983ce6e6fe2dd1e1921b9952fb4e6da882931abd1824c092ed495dec", size = 454138, upload-time = "2025-04-08T10:35:20.586Z" }, + { url = "https://files.pythonhosted.org/packages/3e/a4/86833fd2ea2e50ae28989f5950b5c3f91022d67092bfec08f8300d8b347b/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fe43139b2c0fdc4a14d4f8d5b5d967f7a2777fd3d38ecf5b1ec669b0d7e43c21", size = 458592, upload-time = "2025-04-08T10:35:21.87Z" }, + { url = "https://files.pythonhosted.org/packages/38/7e/42cb8df8be9a37e50dd3a818816501cf7a20d635d76d6bd65aae3dbbff68/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee0822ce1b8a14fe5a066f93edd20aada932acfe348bede8aa2149f1a4489512", size = 487532, upload-time = "2025-04-08T10:35:23.143Z" }, + { url = "https://files.pythonhosted.org/packages/fc/fd/13d26721c85d7f3df6169d8b495fcac8ab0dc8f0945ebea8845de4681dab/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a0dbcb1c2d8f2ab6e0a81c6699b236932bd264d4cef1ac475858d16c403de74d", size = 522865, upload-time = "2025-04-08T10:35:24.702Z" }, + { url = "https://files.pythonhosted.org/packages/a1/0d/7f9ae243c04e96c5455d111e21b09087d0eeaf9a1369e13a01c7d3d82478/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a2014a2b18ad3ca53b1f6c23f8cd94a18ce930c1837bd891262c182640eb40a6", size = 499887, upload-time = "2025-04-08T10:35:25.969Z" }, + { url = "https://files.pythonhosted.org/packages/8e/0f/a257766998e26aca4b3acf2ae97dff04b57071e991a510857d3799247c67/watchfiles-1.0.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f6ae86d5cb647bf58f9f655fcf577f713915a5d69057a0371bc257e2553234", size = 454498, upload-time = "2025-04-08T10:35:27.353Z" }, + { url = "https://files.pythonhosted.org/packages/81/79/8bf142575a03e0af9c3d5f8bcae911ee6683ae93a625d349d4ecf4c8f7df/watchfiles-1.0.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1a7bac2bde1d661fb31f4d4e8e539e178774b76db3c2c17c4bb3e960a5de07a2", size = 630663, upload-time = "2025-04-08T10:35:28.685Z" }, + { url = "https://files.pythonhosted.org/packages/f1/80/abe2e79f610e45c63a70d271caea90c49bbf93eb00fa947fa9b803a1d51f/watchfiles-1.0.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ab626da2fc1ac277bbf752446470b367f84b50295264d2d313e28dc4405d663", size = 625410, upload-time = "2025-04-08T10:35:30.42Z" }, + { url = "https://files.pythonhosted.org/packages/91/6f/bc7fbecb84a41a9069c2c6eb6319f7f7df113adf113e358c57fc1aff7ff5/watchfiles-1.0.5-cp312-cp312-win32.whl", hash = "sha256:9f4571a783914feda92018ef3901dab8caf5b029325b5fe4558c074582815249", size = 277965, upload-time = "2025-04-08T10:35:32.023Z" }, + { url = "https://files.pythonhosted.org/packages/99/a5/bf1c297ea6649ec59e935ab311f63d8af5faa8f0b86993e3282b984263e3/watchfiles-1.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:360a398c3a19672cf93527f7e8d8b60d8275119c5d900f2e184d32483117a705", size = 291693, upload-time = "2025-04-08T10:35:33.225Z" }, + { url = "https://files.pythonhosted.org/packages/7f/7b/fd01087cc21db5c47e5beae507b87965db341cce8a86f9eb12bf5219d4e0/watchfiles-1.0.5-cp312-cp312-win_arm64.whl", hash = "sha256:1a2902ede862969077b97523987c38db28abbe09fb19866e711485d9fbf0d417", size = 283287, upload-time = "2025-04-08T10:35:34.568Z" }, + { url = "https://files.pythonhosted.org/packages/c7/62/435766874b704f39b2fecd8395a29042db2b5ec4005bd34523415e9bd2e0/watchfiles-1.0.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0b289572c33a0deae62daa57e44a25b99b783e5f7aed81b314232b3d3c81a11d", size = 401531, upload-time = "2025-04-08T10:35:35.792Z" }, + { url = "https://files.pythonhosted.org/packages/6e/a6/e52a02c05411b9cb02823e6797ef9bbba0bfaf1bb627da1634d44d8af833/watchfiles-1.0.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a056c2f692d65bf1e99c41045e3bdcaea3cb9e6b5a53dcaf60a5f3bd95fc9763", size = 392417, upload-time = "2025-04-08T10:35:37.048Z" }, + { url = "https://files.pythonhosted.org/packages/3f/53/c4af6819770455932144e0109d4854437769672d7ad897e76e8e1673435d/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9dca99744991fc9850d18015c4f0438865414e50069670f5f7eee08340d8b40", size = 453423, upload-time = "2025-04-08T10:35:38.357Z" }, + { url = "https://files.pythonhosted.org/packages/cb/d1/8e88df58bbbf819b8bc5cfbacd3c79e01b40261cad0fc84d1e1ebd778a07/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:894342d61d355446d02cd3988a7326af344143eb33a2fd5d38482a92072d9563", size = 458185, upload-time = "2025-04-08T10:35:39.708Z" }, + { url = "https://files.pythonhosted.org/packages/ff/70/fffaa11962dd5429e47e478a18736d4e42bec42404f5ee3b92ef1b87ad60/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab44e1580924d1ffd7b3938e02716d5ad190441965138b4aa1d1f31ea0877f04", size = 486696, upload-time = "2025-04-08T10:35:41.469Z" }, + { url = "https://files.pythonhosted.org/packages/39/db/723c0328e8b3692d53eb273797d9a08be6ffb1d16f1c0ba2bdbdc2a3852c/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d6f9367b132078b2ceb8d066ff6c93a970a18c3029cea37bfd7b2d3dd2e5db8f", size = 522327, upload-time = "2025-04-08T10:35:43.289Z" }, + { url = "https://files.pythonhosted.org/packages/cd/05/9fccc43c50c39a76b68343484b9da7b12d42d0859c37c61aec018c967a32/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2e55a9b162e06e3f862fb61e399fe9f05d908d019d87bf5b496a04ef18a970a", size = 499741, upload-time = "2025-04-08T10:35:44.574Z" }, + { url = "https://files.pythonhosted.org/packages/23/14/499e90c37fa518976782b10a18b18db9f55ea73ca14641615056f8194bb3/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0125f91f70e0732a9f8ee01e49515c35d38ba48db507a50c5bdcad9503af5827", size = 453995, upload-time = "2025-04-08T10:35:46.336Z" }, + { url = "https://files.pythonhosted.org/packages/61/d9/f75d6840059320df5adecd2c687fbc18960a7f97b55c300d20f207d48aef/watchfiles-1.0.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:13bb21f8ba3248386337c9fa51c528868e6c34a707f729ab041c846d52a0c69a", size = 629693, upload-time = "2025-04-08T10:35:48.161Z" }, + { url = "https://files.pythonhosted.org/packages/fc/17/180ca383f5061b61406477218c55d66ec118e6c0c51f02d8142895fcf0a9/watchfiles-1.0.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:839ebd0df4a18c5b3c1b890145b5a3f5f64063c2a0d02b13c76d78fe5de34936", size = 624677, upload-time = "2025-04-08T10:35:49.65Z" }, + { url = "https://files.pythonhosted.org/packages/bf/15/714d6ef307f803f236d69ee9d421763707899d6298d9f3183e55e366d9af/watchfiles-1.0.5-cp313-cp313-win32.whl", hash = "sha256:4a8ec1e4e16e2d5bafc9ba82f7aaecfeec990ca7cd27e84fb6f191804ed2fcfc", size = 277804, upload-time = "2025-04-08T10:35:51.093Z" }, + { url = "https://files.pythonhosted.org/packages/a8/b4/c57b99518fadf431f3ef47a610839e46e5f8abf9814f969859d1c65c02c7/watchfiles-1.0.5-cp313-cp313-win_amd64.whl", hash = "sha256:f436601594f15bf406518af922a89dcaab416568edb6f65c4e5bbbad1ea45c11", size = 291087, upload-time = "2025-04-08T10:35:52.458Z" }, + { url = "https://files.pythonhosted.org/packages/1a/03/81f9fcc3963b3fc415cd4b0b2b39ee8cc136c42fb10a36acf38745e9d283/watchfiles-1.0.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f59b870db1f1ae5a9ac28245707d955c8721dd6565e7f411024fa374b5362d1d", size = 405947, upload-time = "2025-04-08T10:36:13.721Z" }, + { url = "https://files.pythonhosted.org/packages/54/97/8c4213a852feb64807ec1d380f42d4fc8bfaef896bdbd94318f8fd7f3e4e/watchfiles-1.0.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9475b0093767e1475095f2aeb1d219fb9664081d403d1dff81342df8cd707034", size = 397276, upload-time = "2025-04-08T10:36:15.131Z" }, + { url = "https://files.pythonhosted.org/packages/78/12/d4464d19860cb9672efa45eec1b08f8472c478ed67dcd30647c51ada7aef/watchfiles-1.0.5-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc533aa50664ebd6c628b2f30591956519462f5d27f951ed03d6c82b2dfd9965", size = 455550, upload-time = "2025-04-08T10:36:16.635Z" }, + { url = "https://files.pythonhosted.org/packages/90/fb/b07bcdf1034d8edeaef4c22f3e9e3157d37c5071b5f9492ffdfa4ad4bed7/watchfiles-1.0.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed1cd825158dcaae36acce7b2db33dcbfd12b30c34317a88b8ed80f0541cc57", size = 455542, upload-time = "2025-04-08T10:36:18.655Z" }, ] [[package]] @@ -1865,68 +1865,68 @@ dependencies = [ { name = "typing-extensions" }, { name = "websockets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7d/1e/fc1f5b5a12615cbdca57d35014cdb9823db7392d73b730fa0d89d6a13f6a/web3-7.12.0.tar.gz", hash = "sha256:08fbe79a2e2503c9820132ebad24ba0372831588cabac5f467999c97ace7dda3", size = 2195693 } +sdist = { url = "https://files.pythonhosted.org/packages/7d/1e/fc1f5b5a12615cbdca57d35014cdb9823db7392d73b730fa0d89d6a13f6a/web3-7.12.0.tar.gz", hash = "sha256:08fbe79a2e2503c9820132ebad24ba0372831588cabac5f467999c97ace7dda3", size = 2195693, upload-time = "2025-05-22T21:06:05.381Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b8/df/0ccf18f244b96a93ba2710f7ce696da1f8dd44ef1126e3603dfb65cd68fe/web3-7.12.0-py3-none-any.whl", hash = "sha256:c7e2b9c1db5a379ef53b45fe8a19bdc2d47ad262039fbf6675794bc40f74bf06", size = 1369328 }, + { url = "https://files.pythonhosted.org/packages/b8/df/0ccf18f244b96a93ba2710f7ce696da1f8dd44ef1126e3603dfb65cd68fe/web3-7.12.0-py3-none-any.whl", hash = "sha256:c7e2b9c1db5a379ef53b45fe8a19bdc2d47ad262039fbf6675794bc40f74bf06", size = 1369328, upload-time = "2025-05-22T21:06:03.124Z" }, ] [[package]] name = "websockets" version = "15.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/da/6462a9f510c0c49837bbc9345aca92d767a56c1fb2939e1579df1e1cdcf7/websockets-15.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d63efaa0cd96cf0c5fe4d581521d9fa87744540d4bc999ae6e08595a1014b45b", size = 175423 }, - { url = "https://files.pythonhosted.org/packages/1c/9f/9d11c1a4eb046a9e106483b9ff69bce7ac880443f00e5ce64261b47b07e7/websockets-15.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac60e3b188ec7574cb761b08d50fcedf9d77f1530352db4eef1707fe9dee7205", size = 173080 }, - { url = "https://files.pythonhosted.org/packages/d5/4f/b462242432d93ea45f297b6179c7333dd0402b855a912a04e7fc61c0d71f/websockets-15.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5756779642579d902eed757b21b0164cd6fe338506a8083eb58af5c372e39d9a", size = 173329 }, - { url = "https://files.pythonhosted.org/packages/6e/0c/6afa1f4644d7ed50284ac59cc70ef8abd44ccf7d45850d989ea7310538d0/websockets-15.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fdfe3e2a29e4db3659dbd5bbf04560cea53dd9610273917799f1cde46aa725e", size = 182312 }, - { url = "https://files.pythonhosted.org/packages/dd/d4/ffc8bd1350b229ca7a4db2a3e1c482cf87cea1baccd0ef3e72bc720caeec/websockets-15.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c2529b320eb9e35af0fa3016c187dffb84a3ecc572bcee7c3ce302bfeba52bf", size = 181319 }, - { url = "https://files.pythonhosted.org/packages/97/3a/5323a6bb94917af13bbb34009fac01e55c51dfde354f63692bf2533ffbc2/websockets-15.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac1e5c9054fe23226fb11e05a6e630837f074174c4c2f0fe442996112a6de4fb", size = 181631 }, - { url = "https://files.pythonhosted.org/packages/a6/cc/1aeb0f7cee59ef065724041bb7ed667b6ab1eeffe5141696cccec2687b66/websockets-15.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5df592cd503496351d6dc14f7cdad49f268d8e618f80dce0cd5a36b93c3fc08d", size = 182016 }, - { url = "https://files.pythonhosted.org/packages/79/f9/c86f8f7af208e4161a7f7e02774e9d0a81c632ae76db2ff22549e1718a51/websockets-15.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0a34631031a8f05657e8e90903e656959234f3a04552259458aac0b0f9ae6fd9", size = 181426 }, - { url = "https://files.pythonhosted.org/packages/c7/b9/828b0bc6753db905b91df6ae477c0b14a141090df64fb17f8a9d7e3516cf/websockets-15.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3d00075aa65772e7ce9e990cab3ff1de702aa09be3940d1dc88d5abf1ab8a09c", size = 181360 }, - { url = "https://files.pythonhosted.org/packages/89/fb/250f5533ec468ba6327055b7d98b9df056fb1ce623b8b6aaafb30b55d02e/websockets-15.0.1-cp310-cp310-win32.whl", hash = "sha256:1234d4ef35db82f5446dca8e35a7da7964d02c127b095e172e54397fb6a6c256", size = 176388 }, - { url = "https://files.pythonhosted.org/packages/1c/46/aca7082012768bb98e5608f01658ff3ac8437e563eca41cf068bd5849a5e/websockets-15.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:39c1fec2c11dc8d89bba6b2bf1556af381611a173ac2b511cf7231622058af41", size = 176830 }, - { url = "https://files.pythonhosted.org/packages/9f/32/18fcd5919c293a398db67443acd33fde142f283853076049824fc58e6f75/websockets-15.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:823c248b690b2fd9303ba00c4f66cd5e2d8c3ba4aa968b2779be9532a4dad431", size = 175423 }, - { url = "https://files.pythonhosted.org/packages/76/70/ba1ad96b07869275ef42e2ce21f07a5b0148936688c2baf7e4a1f60d5058/websockets-15.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678999709e68425ae2593acf2e3ebcbcf2e69885a5ee78f9eb80e6e371f1bf57", size = 173082 }, - { url = "https://files.pythonhosted.org/packages/86/f2/10b55821dd40eb696ce4704a87d57774696f9451108cff0d2824c97e0f97/websockets-15.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d50fd1ee42388dcfb2b3676132c78116490976f1300da28eb629272d5d93e905", size = 173330 }, - { url = "https://files.pythonhosted.org/packages/a5/90/1c37ae8b8a113d3daf1065222b6af61cc44102da95388ac0018fcb7d93d9/websockets-15.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d99e5546bf73dbad5bf3547174cd6cb8ba7273062a23808ffea025ecb1cf8562", size = 182878 }, - { url = "https://files.pythonhosted.org/packages/8e/8d/96e8e288b2a41dffafb78e8904ea7367ee4f891dafc2ab8d87e2124cb3d3/websockets-15.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66dd88c918e3287efc22409d426c8f729688d89a0c587c88971a0faa2c2f3792", size = 181883 }, - { url = "https://files.pythonhosted.org/packages/93/1f/5d6dbf551766308f6f50f8baf8e9860be6182911e8106da7a7f73785f4c4/websockets-15.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dd8327c795b3e3f219760fa603dcae1dcc148172290a8ab15158cf85a953413", size = 182252 }, - { url = "https://files.pythonhosted.org/packages/d4/78/2d4fed9123e6620cbf1706c0de8a1632e1a28e7774d94346d7de1bba2ca3/websockets-15.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8fdc51055e6ff4adeb88d58a11042ec9a5eae317a0a53d12c062c8a8865909e8", size = 182521 }, - { url = "https://files.pythonhosted.org/packages/e7/3b/66d4c1b444dd1a9823c4a81f50231b921bab54eee2f69e70319b4e21f1ca/websockets-15.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:693f0192126df6c2327cce3baa7c06f2a117575e32ab2308f7f8216c29d9e2e3", size = 181958 }, - { url = "https://files.pythonhosted.org/packages/08/ff/e9eed2ee5fed6f76fdd6032ca5cd38c57ca9661430bb3d5fb2872dc8703c/websockets-15.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:54479983bd5fb469c38f2f5c7e3a24f9a4e70594cd68cd1fa6b9340dadaff7cf", size = 181918 }, - { url = "https://files.pythonhosted.org/packages/d8/75/994634a49b7e12532be6a42103597b71098fd25900f7437d6055ed39930a/websockets-15.0.1-cp311-cp311-win32.whl", hash = "sha256:16b6c1b3e57799b9d38427dda63edcbe4926352c47cf88588c0be4ace18dac85", size = 176388 }, - { url = "https://files.pythonhosted.org/packages/98/93/e36c73f78400a65f5e236cd376713c34182e6663f6889cd45a4a04d8f203/websockets-15.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:27ccee0071a0e75d22cb35849b1db43f2ecd3e161041ac1ee9d2352ddf72f065", size = 176828 }, - { url = "https://files.pythonhosted.org/packages/51/6b/4545a0d843594f5d0771e86463606a3988b5a09ca5123136f8a76580dd63/websockets-15.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3e90baa811a5d73f3ca0bcbf32064d663ed81318ab225ee4f427ad4e26e5aff3", size = 175437 }, - { url = "https://files.pythonhosted.org/packages/f4/71/809a0f5f6a06522af902e0f2ea2757f71ead94610010cf570ab5c98e99ed/websockets-15.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:592f1a9fe869c778694f0aa806ba0374e97648ab57936f092fd9d87f8bc03665", size = 173096 }, - { url = "https://files.pythonhosted.org/packages/3d/69/1a681dd6f02180916f116894181eab8b2e25b31e484c5d0eae637ec01f7c/websockets-15.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0701bc3cfcb9164d04a14b149fd74be7347a530ad3bbf15ab2c678a2cd3dd9a2", size = 173332 }, - { url = "https://files.pythonhosted.org/packages/a6/02/0073b3952f5bce97eafbb35757f8d0d54812b6174ed8dd952aa08429bcc3/websockets-15.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8b56bdcdb4505c8078cb6c7157d9811a85790f2f2b3632c7d1462ab5783d215", size = 183152 }, - { url = "https://files.pythonhosted.org/packages/74/45/c205c8480eafd114b428284840da0b1be9ffd0e4f87338dc95dc6ff961a1/websockets-15.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0af68c55afbd5f07986df82831c7bff04846928ea8d1fd7f30052638788bc9b5", size = 182096 }, - { url = "https://files.pythonhosted.org/packages/14/8f/aa61f528fba38578ec553c145857a181384c72b98156f858ca5c8e82d9d3/websockets-15.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64dee438fed052b52e4f98f76c5790513235efaa1ef7f3f2192c392cd7c91b65", size = 182523 }, - { url = "https://files.pythonhosted.org/packages/ec/6d/0267396610add5bc0d0d3e77f546d4cd287200804fe02323797de77dbce9/websockets-15.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d5f6b181bb38171a8ad1d6aa58a67a6aa9d4b38d0f8c5f496b9e42561dfc62fe", size = 182790 }, - { url = "https://files.pythonhosted.org/packages/02/05/c68c5adbf679cf610ae2f74a9b871ae84564462955d991178f95a1ddb7dd/websockets-15.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5d54b09eba2bada6011aea5375542a157637b91029687eb4fdb2dab11059c1b4", size = 182165 }, - { url = "https://files.pythonhosted.org/packages/29/93/bb672df7b2f5faac89761cb5fa34f5cec45a4026c383a4b5761c6cea5c16/websockets-15.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3be571a8b5afed347da347bfcf27ba12b069d9d7f42cb8c7028b5e98bbb12597", size = 182160 }, - { url = "https://files.pythonhosted.org/packages/ff/83/de1f7709376dc3ca9b7eeb4b9a07b4526b14876b6d372a4dc62312bebee0/websockets-15.0.1-cp312-cp312-win32.whl", hash = "sha256:c338ffa0520bdb12fbc527265235639fb76e7bc7faafbb93f6ba80d9c06578a9", size = 176395 }, - { url = "https://files.pythonhosted.org/packages/7d/71/abf2ebc3bbfa40f391ce1428c7168fb20582d0ff57019b69ea20fa698043/websockets-15.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcd5cf9e305d7b8338754470cf69cf81f420459dbae8a3b40cee57417f4614a7", size = 176841 }, - { url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440 }, - { url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098 }, - { url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329 }, - { url = "https://files.pythonhosted.org/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111 }, - { url = "https://files.pythonhosted.org/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054 }, - { url = "https://files.pythonhosted.org/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496 }, - { url = "https://files.pythonhosted.org/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829 }, - { url = "https://files.pythonhosted.org/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217 }, - { url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195 }, - { url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393 }, - { url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837 }, - { url = "https://files.pythonhosted.org/packages/02/9e/d40f779fa16f74d3468357197af8d6ad07e7c5a27ea1ca74ceb38986f77a/websockets-15.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0c9e74d766f2818bb95f84c25be4dea09841ac0f734d1966f415e4edfc4ef1c3", size = 173109 }, - { url = "https://files.pythonhosted.org/packages/bc/cd/5b887b8585a593073fd92f7c23ecd3985cd2c3175025a91b0d69b0551372/websockets-15.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1009ee0c7739c08a0cd59de430d6de452a55e42d6b522de7aa15e6f67db0b8e1", size = 173343 }, - { url = "https://files.pythonhosted.org/packages/fe/ae/d34f7556890341e900a95acf4886833646306269f899d58ad62f588bf410/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d1f20b1c7a2fa82367e04982e708723ba0e7b8d43aa643d3dcd404d74f1475", size = 174599 }, - { url = "https://files.pythonhosted.org/packages/71/e6/5fd43993a87db364ec60fc1d608273a1a465c0caba69176dd160e197ce42/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f29d80eb9a9263b8d109135351caf568cc3f80b9928bccde535c235de55c22d9", size = 174207 }, - { url = "https://files.pythonhosted.org/packages/2b/fb/c492d6daa5ec067c2988ac80c61359ace5c4c674c532985ac5a123436cec/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b359ed09954d7c18bbc1680f380c7301f92c60bf924171629c5db97febb12f04", size = 174155 }, - { url = "https://files.pythonhosted.org/packages/68/a1/dcb68430b1d00b698ae7a7e0194433bce4f07ded185f0ee5fb21e2a2e91e/websockets-15.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:cad21560da69f4ce7658ca2cb83138fb4cf695a2ba3e475e0559e05991aa8122", size = 176884 }, - { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743 }, +sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016, upload-time = "2025-03-05T20:03:41.606Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/da/6462a9f510c0c49837bbc9345aca92d767a56c1fb2939e1579df1e1cdcf7/websockets-15.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d63efaa0cd96cf0c5fe4d581521d9fa87744540d4bc999ae6e08595a1014b45b", size = 175423, upload-time = "2025-03-05T20:01:35.363Z" }, + { url = "https://files.pythonhosted.org/packages/1c/9f/9d11c1a4eb046a9e106483b9ff69bce7ac880443f00e5ce64261b47b07e7/websockets-15.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac60e3b188ec7574cb761b08d50fcedf9d77f1530352db4eef1707fe9dee7205", size = 173080, upload-time = "2025-03-05T20:01:37.304Z" }, + { url = "https://files.pythonhosted.org/packages/d5/4f/b462242432d93ea45f297b6179c7333dd0402b855a912a04e7fc61c0d71f/websockets-15.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5756779642579d902eed757b21b0164cd6fe338506a8083eb58af5c372e39d9a", size = 173329, upload-time = "2025-03-05T20:01:39.668Z" }, + { url = "https://files.pythonhosted.org/packages/6e/0c/6afa1f4644d7ed50284ac59cc70ef8abd44ccf7d45850d989ea7310538d0/websockets-15.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fdfe3e2a29e4db3659dbd5bbf04560cea53dd9610273917799f1cde46aa725e", size = 182312, upload-time = "2025-03-05T20:01:41.815Z" }, + { url = "https://files.pythonhosted.org/packages/dd/d4/ffc8bd1350b229ca7a4db2a3e1c482cf87cea1baccd0ef3e72bc720caeec/websockets-15.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c2529b320eb9e35af0fa3016c187dffb84a3ecc572bcee7c3ce302bfeba52bf", size = 181319, upload-time = "2025-03-05T20:01:43.967Z" }, + { url = "https://files.pythonhosted.org/packages/97/3a/5323a6bb94917af13bbb34009fac01e55c51dfde354f63692bf2533ffbc2/websockets-15.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac1e5c9054fe23226fb11e05a6e630837f074174c4c2f0fe442996112a6de4fb", size = 181631, upload-time = "2025-03-05T20:01:46.104Z" }, + { url = "https://files.pythonhosted.org/packages/a6/cc/1aeb0f7cee59ef065724041bb7ed667b6ab1eeffe5141696cccec2687b66/websockets-15.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5df592cd503496351d6dc14f7cdad49f268d8e618f80dce0cd5a36b93c3fc08d", size = 182016, upload-time = "2025-03-05T20:01:47.603Z" }, + { url = "https://files.pythonhosted.org/packages/79/f9/c86f8f7af208e4161a7f7e02774e9d0a81c632ae76db2ff22549e1718a51/websockets-15.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0a34631031a8f05657e8e90903e656959234f3a04552259458aac0b0f9ae6fd9", size = 181426, upload-time = "2025-03-05T20:01:48.949Z" }, + { url = "https://files.pythonhosted.org/packages/c7/b9/828b0bc6753db905b91df6ae477c0b14a141090df64fb17f8a9d7e3516cf/websockets-15.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3d00075aa65772e7ce9e990cab3ff1de702aa09be3940d1dc88d5abf1ab8a09c", size = 181360, upload-time = "2025-03-05T20:01:50.938Z" }, + { url = "https://files.pythonhosted.org/packages/89/fb/250f5533ec468ba6327055b7d98b9df056fb1ce623b8b6aaafb30b55d02e/websockets-15.0.1-cp310-cp310-win32.whl", hash = "sha256:1234d4ef35db82f5446dca8e35a7da7964d02c127b095e172e54397fb6a6c256", size = 176388, upload-time = "2025-03-05T20:01:52.213Z" }, + { url = "https://files.pythonhosted.org/packages/1c/46/aca7082012768bb98e5608f01658ff3ac8437e563eca41cf068bd5849a5e/websockets-15.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:39c1fec2c11dc8d89bba6b2bf1556af381611a173ac2b511cf7231622058af41", size = 176830, upload-time = "2025-03-05T20:01:53.922Z" }, + { url = "https://files.pythonhosted.org/packages/9f/32/18fcd5919c293a398db67443acd33fde142f283853076049824fc58e6f75/websockets-15.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:823c248b690b2fd9303ba00c4f66cd5e2d8c3ba4aa968b2779be9532a4dad431", size = 175423, upload-time = "2025-03-05T20:01:56.276Z" }, + { url = "https://files.pythonhosted.org/packages/76/70/ba1ad96b07869275ef42e2ce21f07a5b0148936688c2baf7e4a1f60d5058/websockets-15.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678999709e68425ae2593acf2e3ebcbcf2e69885a5ee78f9eb80e6e371f1bf57", size = 173082, upload-time = "2025-03-05T20:01:57.563Z" }, + { url = "https://files.pythonhosted.org/packages/86/f2/10b55821dd40eb696ce4704a87d57774696f9451108cff0d2824c97e0f97/websockets-15.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d50fd1ee42388dcfb2b3676132c78116490976f1300da28eb629272d5d93e905", size = 173330, upload-time = "2025-03-05T20:01:59.063Z" }, + { url = "https://files.pythonhosted.org/packages/a5/90/1c37ae8b8a113d3daf1065222b6af61cc44102da95388ac0018fcb7d93d9/websockets-15.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d99e5546bf73dbad5bf3547174cd6cb8ba7273062a23808ffea025ecb1cf8562", size = 182878, upload-time = "2025-03-05T20:02:00.305Z" }, + { url = "https://files.pythonhosted.org/packages/8e/8d/96e8e288b2a41dffafb78e8904ea7367ee4f891dafc2ab8d87e2124cb3d3/websockets-15.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66dd88c918e3287efc22409d426c8f729688d89a0c587c88971a0faa2c2f3792", size = 181883, upload-time = "2025-03-05T20:02:03.148Z" }, + { url = "https://files.pythonhosted.org/packages/93/1f/5d6dbf551766308f6f50f8baf8e9860be6182911e8106da7a7f73785f4c4/websockets-15.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dd8327c795b3e3f219760fa603dcae1dcc148172290a8ab15158cf85a953413", size = 182252, upload-time = "2025-03-05T20:02:05.29Z" }, + { url = "https://files.pythonhosted.org/packages/d4/78/2d4fed9123e6620cbf1706c0de8a1632e1a28e7774d94346d7de1bba2ca3/websockets-15.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8fdc51055e6ff4adeb88d58a11042ec9a5eae317a0a53d12c062c8a8865909e8", size = 182521, upload-time = "2025-03-05T20:02:07.458Z" }, + { url = "https://files.pythonhosted.org/packages/e7/3b/66d4c1b444dd1a9823c4a81f50231b921bab54eee2f69e70319b4e21f1ca/websockets-15.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:693f0192126df6c2327cce3baa7c06f2a117575e32ab2308f7f8216c29d9e2e3", size = 181958, upload-time = "2025-03-05T20:02:09.842Z" }, + { url = "https://files.pythonhosted.org/packages/08/ff/e9eed2ee5fed6f76fdd6032ca5cd38c57ca9661430bb3d5fb2872dc8703c/websockets-15.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:54479983bd5fb469c38f2f5c7e3a24f9a4e70594cd68cd1fa6b9340dadaff7cf", size = 181918, upload-time = "2025-03-05T20:02:11.968Z" }, + { url = "https://files.pythonhosted.org/packages/d8/75/994634a49b7e12532be6a42103597b71098fd25900f7437d6055ed39930a/websockets-15.0.1-cp311-cp311-win32.whl", hash = "sha256:16b6c1b3e57799b9d38427dda63edcbe4926352c47cf88588c0be4ace18dac85", size = 176388, upload-time = "2025-03-05T20:02:13.32Z" }, + { url = "https://files.pythonhosted.org/packages/98/93/e36c73f78400a65f5e236cd376713c34182e6663f6889cd45a4a04d8f203/websockets-15.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:27ccee0071a0e75d22cb35849b1db43f2ecd3e161041ac1ee9d2352ddf72f065", size = 176828, upload-time = "2025-03-05T20:02:14.585Z" }, + { url = "https://files.pythonhosted.org/packages/51/6b/4545a0d843594f5d0771e86463606a3988b5a09ca5123136f8a76580dd63/websockets-15.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3e90baa811a5d73f3ca0bcbf32064d663ed81318ab225ee4f427ad4e26e5aff3", size = 175437, upload-time = "2025-03-05T20:02:16.706Z" }, + { url = "https://files.pythonhosted.org/packages/f4/71/809a0f5f6a06522af902e0f2ea2757f71ead94610010cf570ab5c98e99ed/websockets-15.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:592f1a9fe869c778694f0aa806ba0374e97648ab57936f092fd9d87f8bc03665", size = 173096, upload-time = "2025-03-05T20:02:18.832Z" }, + { url = "https://files.pythonhosted.org/packages/3d/69/1a681dd6f02180916f116894181eab8b2e25b31e484c5d0eae637ec01f7c/websockets-15.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0701bc3cfcb9164d04a14b149fd74be7347a530ad3bbf15ab2c678a2cd3dd9a2", size = 173332, upload-time = "2025-03-05T20:02:20.187Z" }, + { url = "https://files.pythonhosted.org/packages/a6/02/0073b3952f5bce97eafbb35757f8d0d54812b6174ed8dd952aa08429bcc3/websockets-15.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8b56bdcdb4505c8078cb6c7157d9811a85790f2f2b3632c7d1462ab5783d215", size = 183152, upload-time = "2025-03-05T20:02:22.286Z" }, + { url = "https://files.pythonhosted.org/packages/74/45/c205c8480eafd114b428284840da0b1be9ffd0e4f87338dc95dc6ff961a1/websockets-15.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0af68c55afbd5f07986df82831c7bff04846928ea8d1fd7f30052638788bc9b5", size = 182096, upload-time = "2025-03-05T20:02:24.368Z" }, + { url = "https://files.pythonhosted.org/packages/14/8f/aa61f528fba38578ec553c145857a181384c72b98156f858ca5c8e82d9d3/websockets-15.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64dee438fed052b52e4f98f76c5790513235efaa1ef7f3f2192c392cd7c91b65", size = 182523, upload-time = "2025-03-05T20:02:25.669Z" }, + { url = "https://files.pythonhosted.org/packages/ec/6d/0267396610add5bc0d0d3e77f546d4cd287200804fe02323797de77dbce9/websockets-15.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d5f6b181bb38171a8ad1d6aa58a67a6aa9d4b38d0f8c5f496b9e42561dfc62fe", size = 182790, upload-time = "2025-03-05T20:02:26.99Z" }, + { url = "https://files.pythonhosted.org/packages/02/05/c68c5adbf679cf610ae2f74a9b871ae84564462955d991178f95a1ddb7dd/websockets-15.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5d54b09eba2bada6011aea5375542a157637b91029687eb4fdb2dab11059c1b4", size = 182165, upload-time = "2025-03-05T20:02:30.291Z" }, + { url = "https://files.pythonhosted.org/packages/29/93/bb672df7b2f5faac89761cb5fa34f5cec45a4026c383a4b5761c6cea5c16/websockets-15.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3be571a8b5afed347da347bfcf27ba12b069d9d7f42cb8c7028b5e98bbb12597", size = 182160, upload-time = "2025-03-05T20:02:31.634Z" }, + { url = "https://files.pythonhosted.org/packages/ff/83/de1f7709376dc3ca9b7eeb4b9a07b4526b14876b6d372a4dc62312bebee0/websockets-15.0.1-cp312-cp312-win32.whl", hash = "sha256:c338ffa0520bdb12fbc527265235639fb76e7bc7faafbb93f6ba80d9c06578a9", size = 176395, upload-time = "2025-03-05T20:02:33.017Z" }, + { url = "https://files.pythonhosted.org/packages/7d/71/abf2ebc3bbfa40f391ce1428c7168fb20582d0ff57019b69ea20fa698043/websockets-15.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcd5cf9e305d7b8338754470cf69cf81f420459dbae8a3b40cee57417f4614a7", size = 176841, upload-time = "2025-03-05T20:02:34.498Z" }, + { url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440, upload-time = "2025-03-05T20:02:36.695Z" }, + { url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098, upload-time = "2025-03-05T20:02:37.985Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329, upload-time = "2025-03-05T20:02:39.298Z" }, + { url = "https://files.pythonhosted.org/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111, upload-time = "2025-03-05T20:02:40.595Z" }, + { url = "https://files.pythonhosted.org/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054, upload-time = "2025-03-05T20:02:41.926Z" }, + { url = "https://files.pythonhosted.org/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496, upload-time = "2025-03-05T20:02:43.304Z" }, + { url = "https://files.pythonhosted.org/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829, upload-time = "2025-03-05T20:02:48.812Z" }, + { url = "https://files.pythonhosted.org/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217, upload-time = "2025-03-05T20:02:50.14Z" }, + { url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195, upload-time = "2025-03-05T20:02:51.561Z" }, + { url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393, upload-time = "2025-03-05T20:02:53.814Z" }, + { url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837, upload-time = "2025-03-05T20:02:55.237Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/d40f779fa16f74d3468357197af8d6ad07e7c5a27ea1ca74ceb38986f77a/websockets-15.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0c9e74d766f2818bb95f84c25be4dea09841ac0f734d1966f415e4edfc4ef1c3", size = 173109, upload-time = "2025-03-05T20:03:17.769Z" }, + { url = "https://files.pythonhosted.org/packages/bc/cd/5b887b8585a593073fd92f7c23ecd3985cd2c3175025a91b0d69b0551372/websockets-15.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1009ee0c7739c08a0cd59de430d6de452a55e42d6b522de7aa15e6f67db0b8e1", size = 173343, upload-time = "2025-03-05T20:03:19.094Z" }, + { url = "https://files.pythonhosted.org/packages/fe/ae/d34f7556890341e900a95acf4886833646306269f899d58ad62f588bf410/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d1f20b1c7a2fa82367e04982e708723ba0e7b8d43aa643d3dcd404d74f1475", size = 174599, upload-time = "2025-03-05T20:03:21.1Z" }, + { url = "https://files.pythonhosted.org/packages/71/e6/5fd43993a87db364ec60fc1d608273a1a465c0caba69176dd160e197ce42/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f29d80eb9a9263b8d109135351caf568cc3f80b9928bccde535c235de55c22d9", size = 174207, upload-time = "2025-03-05T20:03:23.221Z" }, + { url = "https://files.pythonhosted.org/packages/2b/fb/c492d6daa5ec067c2988ac80c61359ace5c4c674c532985ac5a123436cec/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b359ed09954d7c18bbc1680f380c7301f92c60bf924171629c5db97febb12f04", size = 174155, upload-time = "2025-03-05T20:03:25.321Z" }, + { url = "https://files.pythonhosted.org/packages/68/a1/dcb68430b1d00b698ae7a7e0194433bce4f07ded185f0ee5fb21e2a2e91e/websockets-15.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:cad21560da69f4ce7658ca2cb83138fb4cf695a2ba3e475e0559e05991aa8122", size = 176884, upload-time = "2025-03-05T20:03:27.934Z" }, + { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" }, ] [[package]] @@ -1936,14 +1936,14 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9f/69/83029f1f6300c5fb2471d621ab06f6ec6b3324685a2ce0f9777fd4a8b71e/werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746", size = 806925 } +sdist = { url = "https://files.pythonhosted.org/packages/9f/69/83029f1f6300c5fb2471d621ab06f6ec6b3324685a2ce0f9777fd4a8b71e/werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746", size = 806925, upload-time = "2024-11-08T15:52:18.093Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/52/24/ab44c871b0f07f491e5d2ad12c9bd7358e527510618cb1b803a88e986db1/werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e", size = 224498 }, + { url = "https://files.pythonhosted.org/packages/52/24/ab44c871b0f07f491e5d2ad12c9bd7358e527510618cb1b803a88e986db1/werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e", size = 224498, upload-time = "2024-11-08T15:52:16.132Z" }, ] [[package]] name = "x402" -version = "0.2.0" +version = "0.2.1" source = { editable = "." } dependencies = [ { name = "eth-account" }, @@ -1993,92 +1993,92 @@ dependencies = [ { name = "multidict" }, { name = "propcache" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3c/fb/efaa23fa4e45537b827620f04cf8f3cd658b76642205162e072703a5b963/yarl-1.20.1.tar.gz", hash = "sha256:d017a4997ee50c91fd5466cef416231bb82177b93b029906cefc542ce14c35ac", size = 186428 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/65/7fed0d774abf47487c64be14e9223749468922817b5e8792b8a64792a1bb/yarl-1.20.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6032e6da6abd41e4acda34d75a816012717000fa6839f37124a47fcefc49bec4", size = 132910 }, - { url = "https://files.pythonhosted.org/packages/8a/7b/988f55a52da99df9e56dc733b8e4e5a6ae2090081dc2754fc8fd34e60aa0/yarl-1.20.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2c7b34d804b8cf9b214f05015c4fee2ebe7ed05cf581e7192c06555c71f4446a", size = 90644 }, - { url = "https://files.pythonhosted.org/packages/f7/de/30d98f03e95d30c7e3cc093759982d038c8833ec2451001d45ef4854edc1/yarl-1.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0c869f2651cc77465f6cd01d938d91a11d9ea5d798738c1dc077f3de0b5e5fed", size = 89322 }, - { url = "https://files.pythonhosted.org/packages/e0/7a/f2f314f5ebfe9200724b0b748de2186b927acb334cf964fd312eb86fc286/yarl-1.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62915e6688eb4d180d93840cda4110995ad50c459bf931b8b3775b37c264af1e", size = 323786 }, - { url = "https://files.pythonhosted.org/packages/15/3f/718d26f189db96d993d14b984ce91de52e76309d0fd1d4296f34039856aa/yarl-1.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:41ebd28167bc6af8abb97fec1a399f412eec5fd61a3ccbe2305a18b84fb4ca73", size = 319627 }, - { url = "https://files.pythonhosted.org/packages/a5/76/8fcfbf5fa2369157b9898962a4a7d96764b287b085b5b3d9ffae69cdefd1/yarl-1.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:21242b4288a6d56f04ea193adde174b7e347ac46ce6bc84989ff7c1b1ecea84e", size = 339149 }, - { url = "https://files.pythonhosted.org/packages/3c/95/d7fc301cc4661785967acc04f54a4a42d5124905e27db27bb578aac49b5c/yarl-1.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bea21cdae6c7eb02ba02a475f37463abfe0a01f5d7200121b03e605d6a0439f8", size = 333327 }, - { url = "https://files.pythonhosted.org/packages/65/94/e21269718349582eee81efc5c1c08ee71c816bfc1585b77d0ec3f58089eb/yarl-1.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f8a891e4a22a89f5dde7862994485e19db246b70bb288d3ce73a34422e55b23", size = 326054 }, - { url = "https://files.pythonhosted.org/packages/32/ae/8616d1f07853704523519f6131d21f092e567c5af93de7e3e94b38d7f065/yarl-1.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd803820d44c8853a109a34e3660e5a61beae12970da479cf44aa2954019bf70", size = 315035 }, - { url = "https://files.pythonhosted.org/packages/48/aa/0ace06280861ef055855333707db5e49c6e3a08840a7ce62682259d0a6c0/yarl-1.20.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b982fa7f74c80d5c0c7b5b38f908971e513380a10fecea528091405f519b9ebb", size = 338962 }, - { url = "https://files.pythonhosted.org/packages/20/52/1e9d0e6916f45a8fb50e6844f01cb34692455f1acd548606cbda8134cd1e/yarl-1.20.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:33f29ecfe0330c570d997bcf1afd304377f2e48f61447f37e846a6058a4d33b2", size = 335399 }, - { url = "https://files.pythonhosted.org/packages/f2/65/60452df742952c630e82f394cd409de10610481d9043aa14c61bf846b7b1/yarl-1.20.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:835ab2cfc74d5eb4a6a528c57f05688099da41cf4957cf08cad38647e4a83b30", size = 338649 }, - { url = "https://files.pythonhosted.org/packages/7b/f5/6cd4ff38dcde57a70f23719a838665ee17079640c77087404c3d34da6727/yarl-1.20.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:46b5e0ccf1943a9a6e766b2c2b8c732c55b34e28be57d8daa2b3c1d1d4009309", size = 358563 }, - { url = "https://files.pythonhosted.org/packages/d1/90/c42eefd79d0d8222cb3227bdd51b640c0c1d0aa33fe4cc86c36eccba77d3/yarl-1.20.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:df47c55f7d74127d1b11251fe6397d84afdde0d53b90bedb46a23c0e534f9d24", size = 357609 }, - { url = "https://files.pythonhosted.org/packages/03/c8/cea6b232cb4617514232e0f8a718153a95b5d82b5290711b201545825532/yarl-1.20.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76d12524d05841276b0e22573f28d5fbcb67589836772ae9244d90dd7d66aa13", size = 350224 }, - { url = "https://files.pythonhosted.org/packages/ce/a3/eaa0ab9712f1f3d01faf43cf6f1f7210ce4ea4a7e9b28b489a2261ca8db9/yarl-1.20.1-cp310-cp310-win32.whl", hash = "sha256:6c4fbf6b02d70e512d7ade4b1f998f237137f1417ab07ec06358ea04f69134f8", size = 81753 }, - { url = "https://files.pythonhosted.org/packages/8f/34/e4abde70a9256465fe31c88ed02c3f8502b7b5dead693a4f350a06413f28/yarl-1.20.1-cp310-cp310-win_amd64.whl", hash = "sha256:aef6c4d69554d44b7f9d923245f8ad9a707d971e6209d51279196d8e8fe1ae16", size = 86817 }, - { url = "https://files.pythonhosted.org/packages/b1/18/893b50efc2350e47a874c5c2d67e55a0ea5df91186b2a6f5ac52eff887cd/yarl-1.20.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:47ee6188fea634bdfaeb2cc420f5b3b17332e6225ce88149a17c413c77ff269e", size = 133833 }, - { url = "https://files.pythonhosted.org/packages/89/ed/b8773448030e6fc47fa797f099ab9eab151a43a25717f9ac043844ad5ea3/yarl-1.20.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d0f6500f69e8402d513e5eedb77a4e1818691e8f45e6b687147963514d84b44b", size = 91070 }, - { url = "https://files.pythonhosted.org/packages/e3/e3/409bd17b1e42619bf69f60e4f031ce1ccb29bd7380117a55529e76933464/yarl-1.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7a8900a42fcdaad568de58887c7b2f602962356908eedb7628eaf6021a6e435b", size = 89818 }, - { url = "https://files.pythonhosted.org/packages/f8/77/64d8431a4d77c856eb2d82aa3de2ad6741365245a29b3a9543cd598ed8c5/yarl-1.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bad6d131fda8ef508b36be3ece16d0902e80b88ea7200f030a0f6c11d9e508d4", size = 347003 }, - { url = "https://files.pythonhosted.org/packages/8d/d2/0c7e4def093dcef0bd9fa22d4d24b023788b0a33b8d0088b51aa51e21e99/yarl-1.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:df018d92fe22aaebb679a7f89fe0c0f368ec497e3dda6cb81a567610f04501f1", size = 336537 }, - { url = "https://files.pythonhosted.org/packages/f0/f3/fc514f4b2cf02cb59d10cbfe228691d25929ce8f72a38db07d3febc3f706/yarl-1.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f969afbb0a9b63c18d0feecf0db09d164b7a44a053e78a7d05f5df163e43833", size = 362358 }, - { url = "https://files.pythonhosted.org/packages/ea/6d/a313ac8d8391381ff9006ac05f1d4331cee3b1efaa833a53d12253733255/yarl-1.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:812303eb4aa98e302886ccda58d6b099e3576b1b9276161469c25803a8db277d", size = 357362 }, - { url = "https://files.pythonhosted.org/packages/00/70/8f78a95d6935a70263d46caa3dd18e1f223cf2f2ff2037baa01a22bc5b22/yarl-1.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98c4a7d166635147924aa0bf9bfe8d8abad6fffa6102de9c99ea04a1376f91e8", size = 348979 }, - { url = "https://files.pythonhosted.org/packages/cb/05/42773027968968f4f15143553970ee36ead27038d627f457cc44bbbeecf3/yarl-1.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12e768f966538e81e6e7550f9086a6236b16e26cd964cf4df35349970f3551cf", size = 337274 }, - { url = "https://files.pythonhosted.org/packages/05/be/665634aa196954156741ea591d2f946f1b78ceee8bb8f28488bf28c0dd62/yarl-1.20.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe41919b9d899661c5c28a8b4b0acf704510b88f27f0934ac7a7bebdd8938d5e", size = 363294 }, - { url = "https://files.pythonhosted.org/packages/eb/90/73448401d36fa4e210ece5579895731f190d5119c4b66b43b52182e88cd5/yarl-1.20.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:8601bc010d1d7780592f3fc1bdc6c72e2b6466ea34569778422943e1a1f3c389", size = 358169 }, - { url = "https://files.pythonhosted.org/packages/c3/b0/fce922d46dc1eb43c811f1889f7daa6001b27a4005587e94878570300881/yarl-1.20.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:daadbdc1f2a9033a2399c42646fbd46da7992e868a5fe9513860122d7fe7a73f", size = 362776 }, - { url = "https://files.pythonhosted.org/packages/f1/0d/b172628fce039dae8977fd22caeff3eeebffd52e86060413f5673767c427/yarl-1.20.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:03aa1e041727cb438ca762628109ef1333498b122e4c76dd858d186a37cec845", size = 381341 }, - { url = "https://files.pythonhosted.org/packages/6b/9b/5b886d7671f4580209e855974fe1cecec409aa4a89ea58b8f0560dc529b1/yarl-1.20.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:642980ef5e0fa1de5fa96d905c7e00cb2c47cb468bfcac5a18c58e27dbf8d8d1", size = 379988 }, - { url = "https://files.pythonhosted.org/packages/73/be/75ef5fd0fcd8f083a5d13f78fd3f009528132a1f2a1d7c925c39fa20aa79/yarl-1.20.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:86971e2795584fe8c002356d3b97ef6c61862720eeff03db2a7c86b678d85b3e", size = 371113 }, - { url = "https://files.pythonhosted.org/packages/50/4f/62faab3b479dfdcb741fe9e3f0323e2a7d5cd1ab2edc73221d57ad4834b2/yarl-1.20.1-cp311-cp311-win32.whl", hash = "sha256:597f40615b8d25812f14562699e287f0dcc035d25eb74da72cae043bb884d773", size = 81485 }, - { url = "https://files.pythonhosted.org/packages/f0/09/d9c7942f8f05c32ec72cd5c8e041c8b29b5807328b68b4801ff2511d4d5e/yarl-1.20.1-cp311-cp311-win_amd64.whl", hash = "sha256:26ef53a9e726e61e9cd1cda6b478f17e350fb5800b4bd1cd9fe81c4d91cfeb2e", size = 86686 }, - { url = "https://files.pythonhosted.org/packages/5f/9a/cb7fad7d73c69f296eda6815e4a2c7ed53fc70c2f136479a91c8e5fbdb6d/yarl-1.20.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdcc4cd244e58593a4379fe60fdee5ac0331f8eb70320a24d591a3be197b94a9", size = 133667 }, - { url = "https://files.pythonhosted.org/packages/67/38/688577a1cb1e656e3971fb66a3492501c5a5df56d99722e57c98249e5b8a/yarl-1.20.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b29a2c385a5f5b9c7d9347e5812b6f7ab267193c62d282a540b4fc528c8a9d2a", size = 91025 }, - { url = "https://files.pythonhosted.org/packages/50/ec/72991ae51febeb11a42813fc259f0d4c8e0507f2b74b5514618d8b640365/yarl-1.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1112ae8154186dfe2de4732197f59c05a83dc814849a5ced892b708033f40dc2", size = 89709 }, - { url = "https://files.pythonhosted.org/packages/99/da/4d798025490e89426e9f976702e5f9482005c548c579bdae792a4c37769e/yarl-1.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90bbd29c4fe234233f7fa2b9b121fb63c321830e5d05b45153a2ca68f7d310ee", size = 352287 }, - { url = "https://files.pythonhosted.org/packages/1a/26/54a15c6a567aac1c61b18aa0f4b8aa2e285a52d547d1be8bf48abe2b3991/yarl-1.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:680e19c7ce3710ac4cd964e90dad99bf9b5029372ba0c7cbfcd55e54d90ea819", size = 345429 }, - { url = "https://files.pythonhosted.org/packages/d6/95/9dcf2386cb875b234353b93ec43e40219e14900e046bf6ac118f94b1e353/yarl-1.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a979218c1fdb4246a05efc2cc23859d47c89af463a90b99b7c56094daf25a16", size = 365429 }, - { url = "https://files.pythonhosted.org/packages/91/b2/33a8750f6a4bc224242a635f5f2cff6d6ad5ba651f6edcccf721992c21a0/yarl-1.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255b468adf57b4a7b65d8aad5b5138dce6a0752c139965711bdcb81bc370e1b6", size = 363862 }, - { url = "https://files.pythonhosted.org/packages/98/28/3ab7acc5b51f4434b181b0cee8f1f4b77a65919700a355fb3617f9488874/yarl-1.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a97d67108e79cfe22e2b430d80d7571ae57d19f17cda8bb967057ca8a7bf5bfd", size = 355616 }, - { url = "https://files.pythonhosted.org/packages/36/a3/f666894aa947a371724ec7cd2e5daa78ee8a777b21509b4252dd7bd15e29/yarl-1.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8570d998db4ddbfb9a590b185a0a33dbf8aafb831d07a5257b4ec9948df9cb0a", size = 339954 }, - { url = "https://files.pythonhosted.org/packages/f1/81/5f466427e09773c04219d3450d7a1256138a010b6c9f0af2d48565e9ad13/yarl-1.20.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:97c75596019baae7c71ccf1d8cc4738bc08134060d0adfcbe5642f778d1dca38", size = 365575 }, - { url = "https://files.pythonhosted.org/packages/2e/e3/e4b0ad8403e97e6c9972dd587388940a032f030ebec196ab81a3b8e94d31/yarl-1.20.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1c48912653e63aef91ff988c5432832692ac5a1d8f0fb8a33091520b5bbe19ef", size = 365061 }, - { url = "https://files.pythonhosted.org/packages/ac/99/b8a142e79eb86c926f9f06452eb13ecb1bb5713bd01dc0038faf5452e544/yarl-1.20.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4c3ae28f3ae1563c50f3d37f064ddb1511ecc1d5584e88c6b7c63cf7702a6d5f", size = 364142 }, - { url = "https://files.pythonhosted.org/packages/34/f2/08ed34a4a506d82a1a3e5bab99ccd930a040f9b6449e9fd050320e45845c/yarl-1.20.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c5e9642f27036283550f5f57dc6156c51084b458570b9d0d96100c8bebb186a8", size = 381894 }, - { url = "https://files.pythonhosted.org/packages/92/f8/9a3fbf0968eac704f681726eff595dce9b49c8a25cd92bf83df209668285/yarl-1.20.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2c26b0c49220d5799f7b22c6838409ee9bc58ee5c95361a4d7831f03cc225b5a", size = 383378 }, - { url = "https://files.pythonhosted.org/packages/af/85/9363f77bdfa1e4d690957cd39d192c4cacd1c58965df0470a4905253b54f/yarl-1.20.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:564ab3d517e3d01c408c67f2e5247aad4019dcf1969982aba3974b4093279004", size = 374069 }, - { url = "https://files.pythonhosted.org/packages/35/99/9918c8739ba271dcd935400cff8b32e3cd319eaf02fcd023d5dcd487a7c8/yarl-1.20.1-cp312-cp312-win32.whl", hash = "sha256:daea0d313868da1cf2fac6b2d3a25c6e3a9e879483244be38c8e6a41f1d876a5", size = 81249 }, - { url = "https://files.pythonhosted.org/packages/eb/83/5d9092950565481b413b31a23e75dd3418ff0a277d6e0abf3729d4d1ce25/yarl-1.20.1-cp312-cp312-win_amd64.whl", hash = "sha256:48ea7d7f9be0487339828a4de0360d7ce0efc06524a48e1810f945c45b813698", size = 86710 }, - { url = "https://files.pythonhosted.org/packages/8a/e1/2411b6d7f769a07687acee88a062af5833cf1966b7266f3d8dfb3d3dc7d3/yarl-1.20.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:0b5ff0fbb7c9f1b1b5ab53330acbfc5247893069e7716840c8e7d5bb7355038a", size = 131811 }, - { url = "https://files.pythonhosted.org/packages/b2/27/584394e1cb76fb771371770eccad35de400e7b434ce3142c2dd27392c968/yarl-1.20.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:14f326acd845c2b2e2eb38fb1346c94f7f3b01a4f5c788f8144f9b630bfff9a3", size = 90078 }, - { url = "https://files.pythonhosted.org/packages/bf/9a/3246ae92d4049099f52d9b0fe3486e3b500e29b7ea872d0f152966fc209d/yarl-1.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f60e4ad5db23f0b96e49c018596707c3ae89f5d0bd97f0ad3684bcbad899f1e7", size = 88748 }, - { url = "https://files.pythonhosted.org/packages/a3/25/35afe384e31115a1a801fbcf84012d7a066d89035befae7c5d4284df1e03/yarl-1.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49bdd1b8e00ce57e68ba51916e4bb04461746e794e7c4d4bbc42ba2f18297691", size = 349595 }, - { url = "https://files.pythonhosted.org/packages/28/2d/8aca6cb2cabc8f12efcb82749b9cefecbccfc7b0384e56cd71058ccee433/yarl-1.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:66252d780b45189975abfed839616e8fd2dbacbdc262105ad7742c6ae58f3e31", size = 342616 }, - { url = "https://files.pythonhosted.org/packages/0b/e9/1312633d16b31acf0098d30440ca855e3492d66623dafb8e25b03d00c3da/yarl-1.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59174e7332f5d153d8f7452a102b103e2e74035ad085f404df2e40e663a22b28", size = 361324 }, - { url = "https://files.pythonhosted.org/packages/bc/a0/688cc99463f12f7669eec7c8acc71ef56a1521b99eab7cd3abb75af887b0/yarl-1.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e3968ec7d92a0c0f9ac34d5ecfd03869ec0cab0697c91a45db3fbbd95fe1b653", size = 359676 }, - { url = "https://files.pythonhosted.org/packages/af/44/46407d7f7a56e9a85a4c207724c9f2c545c060380718eea9088f222ba697/yarl-1.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1a4fbb50e14396ba3d375f68bfe02215d8e7bc3ec49da8341fe3157f59d2ff5", size = 352614 }, - { url = "https://files.pythonhosted.org/packages/b1/91/31163295e82b8d5485d31d9cf7754d973d41915cadce070491778d9c9825/yarl-1.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11a62c839c3a8eac2410e951301309426f368388ff2f33799052787035793b02", size = 336766 }, - { url = "https://files.pythonhosted.org/packages/b4/8e/c41a5bc482121f51c083c4c2bcd16b9e01e1cf8729e380273a952513a21f/yarl-1.20.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:041eaa14f73ff5a8986b4388ac6bb43a77f2ea09bf1913df7a35d4646db69e53", size = 364615 }, - { url = "https://files.pythonhosted.org/packages/e3/5b/61a3b054238d33d70ea06ebba7e58597891b71c699e247df35cc984ab393/yarl-1.20.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:377fae2fef158e8fd9d60b4c8751387b8d1fb121d3d0b8e9b0be07d1b41e83dc", size = 360982 }, - { url = "https://files.pythonhosted.org/packages/df/a3/6a72fb83f8d478cb201d14927bc8040af901811a88e0ff2da7842dd0ed19/yarl-1.20.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1c92f4390e407513f619d49319023664643d3339bd5e5a56a3bebe01bc67ec04", size = 369792 }, - { url = "https://files.pythonhosted.org/packages/7c/af/4cc3c36dfc7c077f8dedb561eb21f69e1e9f2456b91b593882b0b18c19dc/yarl-1.20.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d25ddcf954df1754ab0f86bb696af765c5bfaba39b74095f27eececa049ef9a4", size = 382049 }, - { url = "https://files.pythonhosted.org/packages/19/3a/e54e2c4752160115183a66dc9ee75a153f81f3ab2ba4bf79c3c53b33de34/yarl-1.20.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:909313577e9619dcff8c31a0ea2aa0a2a828341d92673015456b3ae492e7317b", size = 384774 }, - { url = "https://files.pythonhosted.org/packages/9c/20/200ae86dabfca89060ec6447649f219b4cbd94531e425e50d57e5f5ac330/yarl-1.20.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:793fd0580cb9664548c6b83c63b43c477212c0260891ddf86809e1c06c8b08f1", size = 374252 }, - { url = "https://files.pythonhosted.org/packages/83/75/11ee332f2f516b3d094e89448da73d557687f7d137d5a0f48c40ff211487/yarl-1.20.1-cp313-cp313-win32.whl", hash = "sha256:468f6e40285de5a5b3c44981ca3a319a4b208ccc07d526b20b12aeedcfa654b7", size = 81198 }, - { url = "https://files.pythonhosted.org/packages/ba/ba/39b1ecbf51620b40ab402b0fc817f0ff750f6d92712b44689c2c215be89d/yarl-1.20.1-cp313-cp313-win_amd64.whl", hash = "sha256:495b4ef2fea40596bfc0affe3837411d6aa3371abcf31aac0ccc4bdd64d4ef5c", size = 86346 }, - { url = "https://files.pythonhosted.org/packages/43/c7/669c52519dca4c95153c8ad96dd123c79f354a376346b198f438e56ffeb4/yarl-1.20.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:f60233b98423aab21d249a30eb27c389c14929f47be8430efa7dbd91493a729d", size = 138826 }, - { url = "https://files.pythonhosted.org/packages/6a/42/fc0053719b44f6ad04a75d7f05e0e9674d45ef62f2d9ad2c1163e5c05827/yarl-1.20.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:6f3eff4cc3f03d650d8755c6eefc844edde99d641d0dcf4da3ab27141a5f8ddf", size = 93217 }, - { url = "https://files.pythonhosted.org/packages/4f/7f/fa59c4c27e2a076bba0d959386e26eba77eb52ea4a0aac48e3515c186b4c/yarl-1.20.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:69ff8439d8ba832d6bed88af2c2b3445977eba9a4588b787b32945871c2444e3", size = 92700 }, - { url = "https://files.pythonhosted.org/packages/2f/d4/062b2f48e7c93481e88eff97a6312dca15ea200e959f23e96d8ab898c5b8/yarl-1.20.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cf34efa60eb81dd2645a2e13e00bb98b76c35ab5061a3989c7a70f78c85006d", size = 347644 }, - { url = "https://files.pythonhosted.org/packages/89/47/78b7f40d13c8f62b499cc702fdf69e090455518ae544c00a3bf4afc9fc77/yarl-1.20.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8e0fe9364ad0fddab2688ce72cb7a8e61ea42eff3c7caeeb83874a5d479c896c", size = 323452 }, - { url = "https://files.pythonhosted.org/packages/eb/2b/490d3b2dc66f52987d4ee0d3090a147ea67732ce6b4d61e362c1846d0d32/yarl-1.20.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f64fbf81878ba914562c672024089e3401974a39767747691c65080a67b18c1", size = 346378 }, - { url = "https://files.pythonhosted.org/packages/66/ad/775da9c8a94ce925d1537f939a4f17d782efef1f973039d821cbe4bcc211/yarl-1.20.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6342d643bf9a1de97e512e45e4b9560a043347e779a173250824f8b254bd5ce", size = 353261 }, - { url = "https://files.pythonhosted.org/packages/4b/23/0ed0922b47a4f5c6eb9065d5ff1e459747226ddce5c6a4c111e728c9f701/yarl-1.20.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56dac5f452ed25eef0f6e3c6a066c6ab68971d96a9fb441791cad0efba6140d3", size = 335987 }, - { url = "https://files.pythonhosted.org/packages/3e/49/bc728a7fe7d0e9336e2b78f0958a2d6b288ba89f25a1762407a222bf53c3/yarl-1.20.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7d7f497126d65e2cad8dc5f97d34c27b19199b6414a40cb36b52f41b79014be", size = 329361 }, - { url = "https://files.pythonhosted.org/packages/93/8f/b811b9d1f617c83c907e7082a76e2b92b655400e61730cd61a1f67178393/yarl-1.20.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:67e708dfb8e78d8a19169818eeb5c7a80717562de9051bf2413aca8e3696bf16", size = 346460 }, - { url = "https://files.pythonhosted.org/packages/70/fd/af94f04f275f95da2c3b8b5e1d49e3e79f1ed8b6ceb0f1664cbd902773ff/yarl-1.20.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:595c07bc79af2494365cc96ddeb772f76272364ef7c80fb892ef9d0649586513", size = 334486 }, - { url = "https://files.pythonhosted.org/packages/84/65/04c62e82704e7dd0a9b3f61dbaa8447f8507655fd16c51da0637b39b2910/yarl-1.20.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7bdd2f80f4a7df852ab9ab49484a4dee8030023aa536df41f2d922fd57bf023f", size = 342219 }, - { url = "https://files.pythonhosted.org/packages/91/95/459ca62eb958381b342d94ab9a4b6aec1ddec1f7057c487e926f03c06d30/yarl-1.20.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:c03bfebc4ae8d862f853a9757199677ab74ec25424d0ebd68a0027e9c639a390", size = 350693 }, - { url = "https://files.pythonhosted.org/packages/a6/00/d393e82dd955ad20617abc546a8f1aee40534d599ff555ea053d0ec9bf03/yarl-1.20.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:344d1103e9c1523f32a5ed704d576172d2cabed3122ea90b1d4e11fe17c66458", size = 355803 }, - { url = "https://files.pythonhosted.org/packages/9e/ed/c5fb04869b99b717985e244fd93029c7a8e8febdfcffa06093e32d7d44e7/yarl-1.20.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:88cab98aa4e13e1ade8c141daeedd300a4603b7132819c484841bb7af3edce9e", size = 341709 }, - { url = "https://files.pythonhosted.org/packages/24/fd/725b8e73ac2a50e78a4534ac43c6addf5c1c2d65380dd48a9169cc6739a9/yarl-1.20.1-cp313-cp313t-win32.whl", hash = "sha256:b121ff6a7cbd4abc28985b6028235491941b9fe8fe226e6fdc539c977ea1739d", size = 86591 }, - { url = "https://files.pythonhosted.org/packages/94/c3/b2e9f38bc3e11191981d57ea08cab2166e74ea770024a646617c9cddd9f6/yarl-1.20.1-cp313-cp313t-win_amd64.whl", hash = "sha256:541d050a355bbbc27e55d906bc91cb6fe42f96c01413dd0f4ed5a5240513874f", size = 93003 }, - { url = "https://files.pythonhosted.org/packages/b4/2d/2345fce04cfd4bee161bf1e7d9cdc702e3e16109021035dbb24db654a622/yarl-1.20.1-py3-none-any.whl", hash = "sha256:83b8eb083fe4683c6115795d9fc1cfaf2cbbefb19b3a1cb68f6527460f483a77", size = 46542 }, +sdist = { url = "https://files.pythonhosted.org/packages/3c/fb/efaa23fa4e45537b827620f04cf8f3cd658b76642205162e072703a5b963/yarl-1.20.1.tar.gz", hash = "sha256:d017a4997ee50c91fd5466cef416231bb82177b93b029906cefc542ce14c35ac", size = 186428, upload-time = "2025-06-10T00:46:09.923Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/65/7fed0d774abf47487c64be14e9223749468922817b5e8792b8a64792a1bb/yarl-1.20.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6032e6da6abd41e4acda34d75a816012717000fa6839f37124a47fcefc49bec4", size = 132910, upload-time = "2025-06-10T00:42:31.108Z" }, + { url = "https://files.pythonhosted.org/packages/8a/7b/988f55a52da99df9e56dc733b8e4e5a6ae2090081dc2754fc8fd34e60aa0/yarl-1.20.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2c7b34d804b8cf9b214f05015c4fee2ebe7ed05cf581e7192c06555c71f4446a", size = 90644, upload-time = "2025-06-10T00:42:33.851Z" }, + { url = "https://files.pythonhosted.org/packages/f7/de/30d98f03e95d30c7e3cc093759982d038c8833ec2451001d45ef4854edc1/yarl-1.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0c869f2651cc77465f6cd01d938d91a11d9ea5d798738c1dc077f3de0b5e5fed", size = 89322, upload-time = "2025-06-10T00:42:35.688Z" }, + { url = "https://files.pythonhosted.org/packages/e0/7a/f2f314f5ebfe9200724b0b748de2186b927acb334cf964fd312eb86fc286/yarl-1.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62915e6688eb4d180d93840cda4110995ad50c459bf931b8b3775b37c264af1e", size = 323786, upload-time = "2025-06-10T00:42:37.817Z" }, + { url = "https://files.pythonhosted.org/packages/15/3f/718d26f189db96d993d14b984ce91de52e76309d0fd1d4296f34039856aa/yarl-1.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:41ebd28167bc6af8abb97fec1a399f412eec5fd61a3ccbe2305a18b84fb4ca73", size = 319627, upload-time = "2025-06-10T00:42:39.937Z" }, + { url = "https://files.pythonhosted.org/packages/a5/76/8fcfbf5fa2369157b9898962a4a7d96764b287b085b5b3d9ffae69cdefd1/yarl-1.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:21242b4288a6d56f04ea193adde174b7e347ac46ce6bc84989ff7c1b1ecea84e", size = 339149, upload-time = "2025-06-10T00:42:42.627Z" }, + { url = "https://files.pythonhosted.org/packages/3c/95/d7fc301cc4661785967acc04f54a4a42d5124905e27db27bb578aac49b5c/yarl-1.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bea21cdae6c7eb02ba02a475f37463abfe0a01f5d7200121b03e605d6a0439f8", size = 333327, upload-time = "2025-06-10T00:42:44.842Z" }, + { url = "https://files.pythonhosted.org/packages/65/94/e21269718349582eee81efc5c1c08ee71c816bfc1585b77d0ec3f58089eb/yarl-1.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f8a891e4a22a89f5dde7862994485e19db246b70bb288d3ce73a34422e55b23", size = 326054, upload-time = "2025-06-10T00:42:47.149Z" }, + { url = "https://files.pythonhosted.org/packages/32/ae/8616d1f07853704523519f6131d21f092e567c5af93de7e3e94b38d7f065/yarl-1.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd803820d44c8853a109a34e3660e5a61beae12970da479cf44aa2954019bf70", size = 315035, upload-time = "2025-06-10T00:42:48.852Z" }, + { url = "https://files.pythonhosted.org/packages/48/aa/0ace06280861ef055855333707db5e49c6e3a08840a7ce62682259d0a6c0/yarl-1.20.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b982fa7f74c80d5c0c7b5b38f908971e513380a10fecea528091405f519b9ebb", size = 338962, upload-time = "2025-06-10T00:42:51.024Z" }, + { url = "https://files.pythonhosted.org/packages/20/52/1e9d0e6916f45a8fb50e6844f01cb34692455f1acd548606cbda8134cd1e/yarl-1.20.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:33f29ecfe0330c570d997bcf1afd304377f2e48f61447f37e846a6058a4d33b2", size = 335399, upload-time = "2025-06-10T00:42:53.007Z" }, + { url = "https://files.pythonhosted.org/packages/f2/65/60452df742952c630e82f394cd409de10610481d9043aa14c61bf846b7b1/yarl-1.20.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:835ab2cfc74d5eb4a6a528c57f05688099da41cf4957cf08cad38647e4a83b30", size = 338649, upload-time = "2025-06-10T00:42:54.964Z" }, + { url = "https://files.pythonhosted.org/packages/7b/f5/6cd4ff38dcde57a70f23719a838665ee17079640c77087404c3d34da6727/yarl-1.20.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:46b5e0ccf1943a9a6e766b2c2b8c732c55b34e28be57d8daa2b3c1d1d4009309", size = 358563, upload-time = "2025-06-10T00:42:57.28Z" }, + { url = "https://files.pythonhosted.org/packages/d1/90/c42eefd79d0d8222cb3227bdd51b640c0c1d0aa33fe4cc86c36eccba77d3/yarl-1.20.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:df47c55f7d74127d1b11251fe6397d84afdde0d53b90bedb46a23c0e534f9d24", size = 357609, upload-time = "2025-06-10T00:42:59.055Z" }, + { url = "https://files.pythonhosted.org/packages/03/c8/cea6b232cb4617514232e0f8a718153a95b5d82b5290711b201545825532/yarl-1.20.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76d12524d05841276b0e22573f28d5fbcb67589836772ae9244d90dd7d66aa13", size = 350224, upload-time = "2025-06-10T00:43:01.248Z" }, + { url = "https://files.pythonhosted.org/packages/ce/a3/eaa0ab9712f1f3d01faf43cf6f1f7210ce4ea4a7e9b28b489a2261ca8db9/yarl-1.20.1-cp310-cp310-win32.whl", hash = "sha256:6c4fbf6b02d70e512d7ade4b1f998f237137f1417ab07ec06358ea04f69134f8", size = 81753, upload-time = "2025-06-10T00:43:03.486Z" }, + { url = "https://files.pythonhosted.org/packages/8f/34/e4abde70a9256465fe31c88ed02c3f8502b7b5dead693a4f350a06413f28/yarl-1.20.1-cp310-cp310-win_amd64.whl", hash = "sha256:aef6c4d69554d44b7f9d923245f8ad9a707d971e6209d51279196d8e8fe1ae16", size = 86817, upload-time = "2025-06-10T00:43:05.231Z" }, + { url = "https://files.pythonhosted.org/packages/b1/18/893b50efc2350e47a874c5c2d67e55a0ea5df91186b2a6f5ac52eff887cd/yarl-1.20.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:47ee6188fea634bdfaeb2cc420f5b3b17332e6225ce88149a17c413c77ff269e", size = 133833, upload-time = "2025-06-10T00:43:07.393Z" }, + { url = "https://files.pythonhosted.org/packages/89/ed/b8773448030e6fc47fa797f099ab9eab151a43a25717f9ac043844ad5ea3/yarl-1.20.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d0f6500f69e8402d513e5eedb77a4e1818691e8f45e6b687147963514d84b44b", size = 91070, upload-time = "2025-06-10T00:43:09.538Z" }, + { url = "https://files.pythonhosted.org/packages/e3/e3/409bd17b1e42619bf69f60e4f031ce1ccb29bd7380117a55529e76933464/yarl-1.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7a8900a42fcdaad568de58887c7b2f602962356908eedb7628eaf6021a6e435b", size = 89818, upload-time = "2025-06-10T00:43:11.575Z" }, + { url = "https://files.pythonhosted.org/packages/f8/77/64d8431a4d77c856eb2d82aa3de2ad6741365245a29b3a9543cd598ed8c5/yarl-1.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bad6d131fda8ef508b36be3ece16d0902e80b88ea7200f030a0f6c11d9e508d4", size = 347003, upload-time = "2025-06-10T00:43:14.088Z" }, + { url = "https://files.pythonhosted.org/packages/8d/d2/0c7e4def093dcef0bd9fa22d4d24b023788b0a33b8d0088b51aa51e21e99/yarl-1.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:df018d92fe22aaebb679a7f89fe0c0f368ec497e3dda6cb81a567610f04501f1", size = 336537, upload-time = "2025-06-10T00:43:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/f0/f3/fc514f4b2cf02cb59d10cbfe228691d25929ce8f72a38db07d3febc3f706/yarl-1.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f969afbb0a9b63c18d0feecf0db09d164b7a44a053e78a7d05f5df163e43833", size = 362358, upload-time = "2025-06-10T00:43:18.704Z" }, + { url = "https://files.pythonhosted.org/packages/ea/6d/a313ac8d8391381ff9006ac05f1d4331cee3b1efaa833a53d12253733255/yarl-1.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:812303eb4aa98e302886ccda58d6b099e3576b1b9276161469c25803a8db277d", size = 357362, upload-time = "2025-06-10T00:43:20.888Z" }, + { url = "https://files.pythonhosted.org/packages/00/70/8f78a95d6935a70263d46caa3dd18e1f223cf2f2ff2037baa01a22bc5b22/yarl-1.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98c4a7d166635147924aa0bf9bfe8d8abad6fffa6102de9c99ea04a1376f91e8", size = 348979, upload-time = "2025-06-10T00:43:23.169Z" }, + { url = "https://files.pythonhosted.org/packages/cb/05/42773027968968f4f15143553970ee36ead27038d627f457cc44bbbeecf3/yarl-1.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12e768f966538e81e6e7550f9086a6236b16e26cd964cf4df35349970f3551cf", size = 337274, upload-time = "2025-06-10T00:43:27.111Z" }, + { url = "https://files.pythonhosted.org/packages/05/be/665634aa196954156741ea591d2f946f1b78ceee8bb8f28488bf28c0dd62/yarl-1.20.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe41919b9d899661c5c28a8b4b0acf704510b88f27f0934ac7a7bebdd8938d5e", size = 363294, upload-time = "2025-06-10T00:43:28.96Z" }, + { url = "https://files.pythonhosted.org/packages/eb/90/73448401d36fa4e210ece5579895731f190d5119c4b66b43b52182e88cd5/yarl-1.20.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:8601bc010d1d7780592f3fc1bdc6c72e2b6466ea34569778422943e1a1f3c389", size = 358169, upload-time = "2025-06-10T00:43:30.701Z" }, + { url = "https://files.pythonhosted.org/packages/c3/b0/fce922d46dc1eb43c811f1889f7daa6001b27a4005587e94878570300881/yarl-1.20.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:daadbdc1f2a9033a2399c42646fbd46da7992e868a5fe9513860122d7fe7a73f", size = 362776, upload-time = "2025-06-10T00:43:32.51Z" }, + { url = "https://files.pythonhosted.org/packages/f1/0d/b172628fce039dae8977fd22caeff3eeebffd52e86060413f5673767c427/yarl-1.20.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:03aa1e041727cb438ca762628109ef1333498b122e4c76dd858d186a37cec845", size = 381341, upload-time = "2025-06-10T00:43:34.543Z" }, + { url = "https://files.pythonhosted.org/packages/6b/9b/5b886d7671f4580209e855974fe1cecec409aa4a89ea58b8f0560dc529b1/yarl-1.20.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:642980ef5e0fa1de5fa96d905c7e00cb2c47cb468bfcac5a18c58e27dbf8d8d1", size = 379988, upload-time = "2025-06-10T00:43:36.489Z" }, + { url = "https://files.pythonhosted.org/packages/73/be/75ef5fd0fcd8f083a5d13f78fd3f009528132a1f2a1d7c925c39fa20aa79/yarl-1.20.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:86971e2795584fe8c002356d3b97ef6c61862720eeff03db2a7c86b678d85b3e", size = 371113, upload-time = "2025-06-10T00:43:38.592Z" }, + { url = "https://files.pythonhosted.org/packages/50/4f/62faab3b479dfdcb741fe9e3f0323e2a7d5cd1ab2edc73221d57ad4834b2/yarl-1.20.1-cp311-cp311-win32.whl", hash = "sha256:597f40615b8d25812f14562699e287f0dcc035d25eb74da72cae043bb884d773", size = 81485, upload-time = "2025-06-10T00:43:41.038Z" }, + { url = "https://files.pythonhosted.org/packages/f0/09/d9c7942f8f05c32ec72cd5c8e041c8b29b5807328b68b4801ff2511d4d5e/yarl-1.20.1-cp311-cp311-win_amd64.whl", hash = "sha256:26ef53a9e726e61e9cd1cda6b478f17e350fb5800b4bd1cd9fe81c4d91cfeb2e", size = 86686, upload-time = "2025-06-10T00:43:42.692Z" }, + { url = "https://files.pythonhosted.org/packages/5f/9a/cb7fad7d73c69f296eda6815e4a2c7ed53fc70c2f136479a91c8e5fbdb6d/yarl-1.20.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdcc4cd244e58593a4379fe60fdee5ac0331f8eb70320a24d591a3be197b94a9", size = 133667, upload-time = "2025-06-10T00:43:44.369Z" }, + { url = "https://files.pythonhosted.org/packages/67/38/688577a1cb1e656e3971fb66a3492501c5a5df56d99722e57c98249e5b8a/yarl-1.20.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b29a2c385a5f5b9c7d9347e5812b6f7ab267193c62d282a540b4fc528c8a9d2a", size = 91025, upload-time = "2025-06-10T00:43:46.295Z" }, + { url = "https://files.pythonhosted.org/packages/50/ec/72991ae51febeb11a42813fc259f0d4c8e0507f2b74b5514618d8b640365/yarl-1.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1112ae8154186dfe2de4732197f59c05a83dc814849a5ced892b708033f40dc2", size = 89709, upload-time = "2025-06-10T00:43:48.22Z" }, + { url = "https://files.pythonhosted.org/packages/99/da/4d798025490e89426e9f976702e5f9482005c548c579bdae792a4c37769e/yarl-1.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90bbd29c4fe234233f7fa2b9b121fb63c321830e5d05b45153a2ca68f7d310ee", size = 352287, upload-time = "2025-06-10T00:43:49.924Z" }, + { url = "https://files.pythonhosted.org/packages/1a/26/54a15c6a567aac1c61b18aa0f4b8aa2e285a52d547d1be8bf48abe2b3991/yarl-1.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:680e19c7ce3710ac4cd964e90dad99bf9b5029372ba0c7cbfcd55e54d90ea819", size = 345429, upload-time = "2025-06-10T00:43:51.7Z" }, + { url = "https://files.pythonhosted.org/packages/d6/95/9dcf2386cb875b234353b93ec43e40219e14900e046bf6ac118f94b1e353/yarl-1.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a979218c1fdb4246a05efc2cc23859d47c89af463a90b99b7c56094daf25a16", size = 365429, upload-time = "2025-06-10T00:43:53.494Z" }, + { url = "https://files.pythonhosted.org/packages/91/b2/33a8750f6a4bc224242a635f5f2cff6d6ad5ba651f6edcccf721992c21a0/yarl-1.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255b468adf57b4a7b65d8aad5b5138dce6a0752c139965711bdcb81bc370e1b6", size = 363862, upload-time = "2025-06-10T00:43:55.766Z" }, + { url = "https://files.pythonhosted.org/packages/98/28/3ab7acc5b51f4434b181b0cee8f1f4b77a65919700a355fb3617f9488874/yarl-1.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a97d67108e79cfe22e2b430d80d7571ae57d19f17cda8bb967057ca8a7bf5bfd", size = 355616, upload-time = "2025-06-10T00:43:58.056Z" }, + { url = "https://files.pythonhosted.org/packages/36/a3/f666894aa947a371724ec7cd2e5daa78ee8a777b21509b4252dd7bd15e29/yarl-1.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8570d998db4ddbfb9a590b185a0a33dbf8aafb831d07a5257b4ec9948df9cb0a", size = 339954, upload-time = "2025-06-10T00:43:59.773Z" }, + { url = "https://files.pythonhosted.org/packages/f1/81/5f466427e09773c04219d3450d7a1256138a010b6c9f0af2d48565e9ad13/yarl-1.20.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:97c75596019baae7c71ccf1d8cc4738bc08134060d0adfcbe5642f778d1dca38", size = 365575, upload-time = "2025-06-10T00:44:02.051Z" }, + { url = "https://files.pythonhosted.org/packages/2e/e3/e4b0ad8403e97e6c9972dd587388940a032f030ebec196ab81a3b8e94d31/yarl-1.20.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1c48912653e63aef91ff988c5432832692ac5a1d8f0fb8a33091520b5bbe19ef", size = 365061, upload-time = "2025-06-10T00:44:04.196Z" }, + { url = "https://files.pythonhosted.org/packages/ac/99/b8a142e79eb86c926f9f06452eb13ecb1bb5713bd01dc0038faf5452e544/yarl-1.20.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4c3ae28f3ae1563c50f3d37f064ddb1511ecc1d5584e88c6b7c63cf7702a6d5f", size = 364142, upload-time = "2025-06-10T00:44:06.527Z" }, + { url = "https://files.pythonhosted.org/packages/34/f2/08ed34a4a506d82a1a3e5bab99ccd930a040f9b6449e9fd050320e45845c/yarl-1.20.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c5e9642f27036283550f5f57dc6156c51084b458570b9d0d96100c8bebb186a8", size = 381894, upload-time = "2025-06-10T00:44:08.379Z" }, + { url = "https://files.pythonhosted.org/packages/92/f8/9a3fbf0968eac704f681726eff595dce9b49c8a25cd92bf83df209668285/yarl-1.20.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2c26b0c49220d5799f7b22c6838409ee9bc58ee5c95361a4d7831f03cc225b5a", size = 383378, upload-time = "2025-06-10T00:44:10.51Z" }, + { url = "https://files.pythonhosted.org/packages/af/85/9363f77bdfa1e4d690957cd39d192c4cacd1c58965df0470a4905253b54f/yarl-1.20.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:564ab3d517e3d01c408c67f2e5247aad4019dcf1969982aba3974b4093279004", size = 374069, upload-time = "2025-06-10T00:44:12.834Z" }, + { url = "https://files.pythonhosted.org/packages/35/99/9918c8739ba271dcd935400cff8b32e3cd319eaf02fcd023d5dcd487a7c8/yarl-1.20.1-cp312-cp312-win32.whl", hash = "sha256:daea0d313868da1cf2fac6b2d3a25c6e3a9e879483244be38c8e6a41f1d876a5", size = 81249, upload-time = "2025-06-10T00:44:14.731Z" }, + { url = "https://files.pythonhosted.org/packages/eb/83/5d9092950565481b413b31a23e75dd3418ff0a277d6e0abf3729d4d1ce25/yarl-1.20.1-cp312-cp312-win_amd64.whl", hash = "sha256:48ea7d7f9be0487339828a4de0360d7ce0efc06524a48e1810f945c45b813698", size = 86710, upload-time = "2025-06-10T00:44:16.716Z" }, + { url = "https://files.pythonhosted.org/packages/8a/e1/2411b6d7f769a07687acee88a062af5833cf1966b7266f3d8dfb3d3dc7d3/yarl-1.20.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:0b5ff0fbb7c9f1b1b5ab53330acbfc5247893069e7716840c8e7d5bb7355038a", size = 131811, upload-time = "2025-06-10T00:44:18.933Z" }, + { url = "https://files.pythonhosted.org/packages/b2/27/584394e1cb76fb771371770eccad35de400e7b434ce3142c2dd27392c968/yarl-1.20.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:14f326acd845c2b2e2eb38fb1346c94f7f3b01a4f5c788f8144f9b630bfff9a3", size = 90078, upload-time = "2025-06-10T00:44:20.635Z" }, + { url = "https://files.pythonhosted.org/packages/bf/9a/3246ae92d4049099f52d9b0fe3486e3b500e29b7ea872d0f152966fc209d/yarl-1.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f60e4ad5db23f0b96e49c018596707c3ae89f5d0bd97f0ad3684bcbad899f1e7", size = 88748, upload-time = "2025-06-10T00:44:22.34Z" }, + { url = "https://files.pythonhosted.org/packages/a3/25/35afe384e31115a1a801fbcf84012d7a066d89035befae7c5d4284df1e03/yarl-1.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49bdd1b8e00ce57e68ba51916e4bb04461746e794e7c4d4bbc42ba2f18297691", size = 349595, upload-time = "2025-06-10T00:44:24.314Z" }, + { url = "https://files.pythonhosted.org/packages/28/2d/8aca6cb2cabc8f12efcb82749b9cefecbccfc7b0384e56cd71058ccee433/yarl-1.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:66252d780b45189975abfed839616e8fd2dbacbdc262105ad7742c6ae58f3e31", size = 342616, upload-time = "2025-06-10T00:44:26.167Z" }, + { url = "https://files.pythonhosted.org/packages/0b/e9/1312633d16b31acf0098d30440ca855e3492d66623dafb8e25b03d00c3da/yarl-1.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59174e7332f5d153d8f7452a102b103e2e74035ad085f404df2e40e663a22b28", size = 361324, upload-time = "2025-06-10T00:44:27.915Z" }, + { url = "https://files.pythonhosted.org/packages/bc/a0/688cc99463f12f7669eec7c8acc71ef56a1521b99eab7cd3abb75af887b0/yarl-1.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e3968ec7d92a0c0f9ac34d5ecfd03869ec0cab0697c91a45db3fbbd95fe1b653", size = 359676, upload-time = "2025-06-10T00:44:30.041Z" }, + { url = "https://files.pythonhosted.org/packages/af/44/46407d7f7a56e9a85a4c207724c9f2c545c060380718eea9088f222ba697/yarl-1.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1a4fbb50e14396ba3d375f68bfe02215d8e7bc3ec49da8341fe3157f59d2ff5", size = 352614, upload-time = "2025-06-10T00:44:32.171Z" }, + { url = "https://files.pythonhosted.org/packages/b1/91/31163295e82b8d5485d31d9cf7754d973d41915cadce070491778d9c9825/yarl-1.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11a62c839c3a8eac2410e951301309426f368388ff2f33799052787035793b02", size = 336766, upload-time = "2025-06-10T00:44:34.494Z" }, + { url = "https://files.pythonhosted.org/packages/b4/8e/c41a5bc482121f51c083c4c2bcd16b9e01e1cf8729e380273a952513a21f/yarl-1.20.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:041eaa14f73ff5a8986b4388ac6bb43a77f2ea09bf1913df7a35d4646db69e53", size = 364615, upload-time = "2025-06-10T00:44:36.856Z" }, + { url = "https://files.pythonhosted.org/packages/e3/5b/61a3b054238d33d70ea06ebba7e58597891b71c699e247df35cc984ab393/yarl-1.20.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:377fae2fef158e8fd9d60b4c8751387b8d1fb121d3d0b8e9b0be07d1b41e83dc", size = 360982, upload-time = "2025-06-10T00:44:39.141Z" }, + { url = "https://files.pythonhosted.org/packages/df/a3/6a72fb83f8d478cb201d14927bc8040af901811a88e0ff2da7842dd0ed19/yarl-1.20.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1c92f4390e407513f619d49319023664643d3339bd5e5a56a3bebe01bc67ec04", size = 369792, upload-time = "2025-06-10T00:44:40.934Z" }, + { url = "https://files.pythonhosted.org/packages/7c/af/4cc3c36dfc7c077f8dedb561eb21f69e1e9f2456b91b593882b0b18c19dc/yarl-1.20.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d25ddcf954df1754ab0f86bb696af765c5bfaba39b74095f27eececa049ef9a4", size = 382049, upload-time = "2025-06-10T00:44:42.854Z" }, + { url = "https://files.pythonhosted.org/packages/19/3a/e54e2c4752160115183a66dc9ee75a153f81f3ab2ba4bf79c3c53b33de34/yarl-1.20.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:909313577e9619dcff8c31a0ea2aa0a2a828341d92673015456b3ae492e7317b", size = 384774, upload-time = "2025-06-10T00:44:45.275Z" }, + { url = "https://files.pythonhosted.org/packages/9c/20/200ae86dabfca89060ec6447649f219b4cbd94531e425e50d57e5f5ac330/yarl-1.20.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:793fd0580cb9664548c6b83c63b43c477212c0260891ddf86809e1c06c8b08f1", size = 374252, upload-time = "2025-06-10T00:44:47.31Z" }, + { url = "https://files.pythonhosted.org/packages/83/75/11ee332f2f516b3d094e89448da73d557687f7d137d5a0f48c40ff211487/yarl-1.20.1-cp313-cp313-win32.whl", hash = "sha256:468f6e40285de5a5b3c44981ca3a319a4b208ccc07d526b20b12aeedcfa654b7", size = 81198, upload-time = "2025-06-10T00:44:49.164Z" }, + { url = "https://files.pythonhosted.org/packages/ba/ba/39b1ecbf51620b40ab402b0fc817f0ff750f6d92712b44689c2c215be89d/yarl-1.20.1-cp313-cp313-win_amd64.whl", hash = "sha256:495b4ef2fea40596bfc0affe3837411d6aa3371abcf31aac0ccc4bdd64d4ef5c", size = 86346, upload-time = "2025-06-10T00:44:51.182Z" }, + { url = "https://files.pythonhosted.org/packages/43/c7/669c52519dca4c95153c8ad96dd123c79f354a376346b198f438e56ffeb4/yarl-1.20.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:f60233b98423aab21d249a30eb27c389c14929f47be8430efa7dbd91493a729d", size = 138826, upload-time = "2025-06-10T00:44:52.883Z" }, + { url = "https://files.pythonhosted.org/packages/6a/42/fc0053719b44f6ad04a75d7f05e0e9674d45ef62f2d9ad2c1163e5c05827/yarl-1.20.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:6f3eff4cc3f03d650d8755c6eefc844edde99d641d0dcf4da3ab27141a5f8ddf", size = 93217, upload-time = "2025-06-10T00:44:54.658Z" }, + { url = "https://files.pythonhosted.org/packages/4f/7f/fa59c4c27e2a076bba0d959386e26eba77eb52ea4a0aac48e3515c186b4c/yarl-1.20.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:69ff8439d8ba832d6bed88af2c2b3445977eba9a4588b787b32945871c2444e3", size = 92700, upload-time = "2025-06-10T00:44:56.784Z" }, + { url = "https://files.pythonhosted.org/packages/2f/d4/062b2f48e7c93481e88eff97a6312dca15ea200e959f23e96d8ab898c5b8/yarl-1.20.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cf34efa60eb81dd2645a2e13e00bb98b76c35ab5061a3989c7a70f78c85006d", size = 347644, upload-time = "2025-06-10T00:44:59.071Z" }, + { url = "https://files.pythonhosted.org/packages/89/47/78b7f40d13c8f62b499cc702fdf69e090455518ae544c00a3bf4afc9fc77/yarl-1.20.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8e0fe9364ad0fddab2688ce72cb7a8e61ea42eff3c7caeeb83874a5d479c896c", size = 323452, upload-time = "2025-06-10T00:45:01.605Z" }, + { url = "https://files.pythonhosted.org/packages/eb/2b/490d3b2dc66f52987d4ee0d3090a147ea67732ce6b4d61e362c1846d0d32/yarl-1.20.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f64fbf81878ba914562c672024089e3401974a39767747691c65080a67b18c1", size = 346378, upload-time = "2025-06-10T00:45:03.946Z" }, + { url = "https://files.pythonhosted.org/packages/66/ad/775da9c8a94ce925d1537f939a4f17d782efef1f973039d821cbe4bcc211/yarl-1.20.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6342d643bf9a1de97e512e45e4b9560a043347e779a173250824f8b254bd5ce", size = 353261, upload-time = "2025-06-10T00:45:05.992Z" }, + { url = "https://files.pythonhosted.org/packages/4b/23/0ed0922b47a4f5c6eb9065d5ff1e459747226ddce5c6a4c111e728c9f701/yarl-1.20.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56dac5f452ed25eef0f6e3c6a066c6ab68971d96a9fb441791cad0efba6140d3", size = 335987, upload-time = "2025-06-10T00:45:08.227Z" }, + { url = "https://files.pythonhosted.org/packages/3e/49/bc728a7fe7d0e9336e2b78f0958a2d6b288ba89f25a1762407a222bf53c3/yarl-1.20.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7d7f497126d65e2cad8dc5f97d34c27b19199b6414a40cb36b52f41b79014be", size = 329361, upload-time = "2025-06-10T00:45:10.11Z" }, + { url = "https://files.pythonhosted.org/packages/93/8f/b811b9d1f617c83c907e7082a76e2b92b655400e61730cd61a1f67178393/yarl-1.20.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:67e708dfb8e78d8a19169818eeb5c7a80717562de9051bf2413aca8e3696bf16", size = 346460, upload-time = "2025-06-10T00:45:12.055Z" }, + { url = "https://files.pythonhosted.org/packages/70/fd/af94f04f275f95da2c3b8b5e1d49e3e79f1ed8b6ceb0f1664cbd902773ff/yarl-1.20.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:595c07bc79af2494365cc96ddeb772f76272364ef7c80fb892ef9d0649586513", size = 334486, upload-time = "2025-06-10T00:45:13.995Z" }, + { url = "https://files.pythonhosted.org/packages/84/65/04c62e82704e7dd0a9b3f61dbaa8447f8507655fd16c51da0637b39b2910/yarl-1.20.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7bdd2f80f4a7df852ab9ab49484a4dee8030023aa536df41f2d922fd57bf023f", size = 342219, upload-time = "2025-06-10T00:45:16.479Z" }, + { url = "https://files.pythonhosted.org/packages/91/95/459ca62eb958381b342d94ab9a4b6aec1ddec1f7057c487e926f03c06d30/yarl-1.20.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:c03bfebc4ae8d862f853a9757199677ab74ec25424d0ebd68a0027e9c639a390", size = 350693, upload-time = "2025-06-10T00:45:18.399Z" }, + { url = "https://files.pythonhosted.org/packages/a6/00/d393e82dd955ad20617abc546a8f1aee40534d599ff555ea053d0ec9bf03/yarl-1.20.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:344d1103e9c1523f32a5ed704d576172d2cabed3122ea90b1d4e11fe17c66458", size = 355803, upload-time = "2025-06-10T00:45:20.677Z" }, + { url = "https://files.pythonhosted.org/packages/9e/ed/c5fb04869b99b717985e244fd93029c7a8e8febdfcffa06093e32d7d44e7/yarl-1.20.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:88cab98aa4e13e1ade8c141daeedd300a4603b7132819c484841bb7af3edce9e", size = 341709, upload-time = "2025-06-10T00:45:23.221Z" }, + { url = "https://files.pythonhosted.org/packages/24/fd/725b8e73ac2a50e78a4534ac43c6addf5c1c2d65380dd48a9169cc6739a9/yarl-1.20.1-cp313-cp313t-win32.whl", hash = "sha256:b121ff6a7cbd4abc28985b6028235491941b9fe8fe226e6fdc539c977ea1739d", size = 86591, upload-time = "2025-06-10T00:45:25.793Z" }, + { url = "https://files.pythonhosted.org/packages/94/c3/b2e9f38bc3e11191981d57ea08cab2166e74ea770024a646617c9cddd9f6/yarl-1.20.1-cp313-cp313t-win_amd64.whl", hash = "sha256:541d050a355bbbc27e55d906bc91cb6fe42f96c01413dd0f4ed5a5240513874f", size = 93003, upload-time = "2025-06-10T00:45:27.752Z" }, + { url = "https://files.pythonhosted.org/packages/b4/2d/2345fce04cfd4bee161bf1e7d9cdc702e3e16109021035dbb24db654a622/yarl-1.20.1-py3-none-any.whl", hash = "sha256:83b8eb083fe4683c6115795d9fc1cfaf2cbbefb19b3a1cb68f6527460f483a77", size = 46542, upload-time = "2025-06-10T00:46:07.521Z" }, ] diff --git a/specs/schemes/exact/scheme_exact.md b/specs/schemes/exact/scheme_exact.md index 60920a093..af96964d0 100644 --- a/specs/schemes/exact/scheme_exact.md +++ b/specs/schemes/exact/scheme_exact.md @@ -12,3 +12,15 @@ amount of funds they need to be transferred. - An LLM paying to use a tool ## Appendix + +## Critical Validation Requirements + +While implementation details vary by network, facilitators MUST enforce security constraints that prevent sponsorship abuse. Examples include: + +### SVM + +- Fee payer safety: the fee payer MUST NOT appear as an account in sensitive instructions or be the transfer authority/source. +- Destination correctness: the receiver MUST match the `payTo` derived destination for the specified `asset`. +- Amount exactness: the transferred amount MUST equal `maxAmountRequired`. + +Network-specific rules and exact instruction layouts are defined in the per-network scheme documents. For Solana (SVM), see `scheme_exact_svm.md`. diff --git a/specs/schemes/exact/scheme_exact_svm.md b/specs/schemes/exact/scheme_exact_svm.md index 4e8e2105e..ab5cea984 100644 --- a/specs/schemes/exact/scheme_exact_svm.md +++ b/specs/schemes/exact/scheme_exact_svm.md @@ -10,24 +10,23 @@ This scheme facilitates payments of a specific amount of an SPL token on the Sol ## Protocol Flow -The protocol flow for `exact` on Solana is client-driven. +The protocol flow for `exact` on Solana is client-driven. 1. **Client** makes an HTTP request to a **Resource Server**. 2. **Resource Server** responds with a `402 Payment Required` status. The response body contains the `paymentRequirements` for the `exact` scheme. Critically, the `extra` field in the requirements contains a **feePayer** which is the public address of the identity that will pay the fee for the transaction. This will typically be the facilitator. -3. **Client** creates a transaction that contains a transfer of an asset to the resource server's wallet address for a specified amount. +3. **Client** creates a transaction that contains a transfer of an asset to the resource server's wallet address for a specified amount. 4. **Client** signs the transaction with their wallet. This results in a partially signed transaction (since the signature of the facilitator that will sponsor the transaction is still missing). 5. **Client** serializes the partially signed transaction and encodes it as a Base64 string. 6. **Client** sends a new HTTP request to the resource server with the `X-PAYMENT` header containing the Base64-encoded partially-signed transaction payload. 7. **Resource Server** receives the request and forwards the `X-PAYMENT` header and `paymentRequirements` to a **Facilitator Server's** `/verify` endpoint. 8. **Facilitator** decodes and deserializes the proposed transaction. 9. **Facilitator** inspects the transaction to ensure it is valid and only contains the expected payment instruction. -10. **Facilitator** returns a response to the **Resource Server** verifying the **client** transaction. +10. **Facilitator** returns a response to the **Resource Server** verifying the **client** transaction. 11. **Resource Server**, upon successful verification, forwards the payload to the facilitator's `/settle` endpoint. 12. **Facilitator Server** provides its final signature as the `feePayer` and submits the now fully-signed transaction to the Solana network. 13. Upon successful on-chain settlement, the **Facilitator Server** responds to the **Resource Server**. 14. **Resource Server** grants the **Client** access to the resource in its response. - ## `PaymentRequirements` for `exact` In addition to the standard x402 `PaymentRequirements` fields, the `exact` scheme on Solana requires the following inside the `extra` field: @@ -50,13 +49,12 @@ In addition to the standard x402 `PaymentRequirements` fields, the `exact` schem } ``` -- `asset`: The public key of the token mint. -- `extra.feePayer`: The public key of the account that will pay for the transaction fees. This is typically the facilitator's public key. - +- `asset`: The public key of the token mint. +- `extra.feePayer`: The public key of the account that will pay for the transaction fees. This is typically the facilitator's public key. ## `X-PAYMENT` Header Payload -The `X-PAYMENT` header is base64 encoded and sent in the request from the client to the resource server when paying for a resource. +The `X-PAYMENT` header is base64 encoded and sent in the request from the client to the resource server when paying for a resource. Once decoded, the `X-PAYMENT` header is a JSON string with the following properties: @@ -73,7 +71,6 @@ Once decoded, the `X-PAYMENT` header is a JSON string with the following propert The `payload` field contains the base64-encoded, serialized, **partially-signed** versioned Solana transaction. - ## `X-PAYMENT-RESPONSE` Header Payload The `X-PAYMENT-RESPONSE` header is base64 encoded and returned to the client from the resource server. @@ -87,4 +84,43 @@ Once decoded, the `X-PAYMENT-RESPONSE` is a JSON string with the following prope "network": "solana" | "solana-devnet", "payer": "base58 encoded public address of the transaction fee payer" } -``` \ No newline at end of file +``` + +## Facilitator Verification Rules (MUST) + +A facilitator verifying an `exact`-scheme SVM payment MUST enforce all of the following checks before sponsoring and signing the transaction: + +1. Instruction layout + +- The decompiled transaction MUST contain either 3 or 4 instructions in this exact order: + 1. Compute Budget: Set Compute Unit Limit + 2. Compute Budget: Set Compute Unit Price + 3. Optional: Associated Token Account Create (when the destination ATA does not yet exist) + 4. SPL Token or Token-2022 TransferChecked + +2. Fee payer (facilitator) safety + +- The configured fee payer address MUST NOT appear in the `accounts` of any instruction in the transaction. +- The fee payer MUST NOT be the `authority` for the TransferChecked instruction. +- The fee payer MUST NOT be the `source` of the transferred funds. + +3. Compute budget validity + +- The program for instructions (1) and (2) MUST be `ComputeBudget` with the correct discriminators (2 = SetLimit, 3 = SetPrice). +- The compute unit price MUST be bounded to prevent gas abuse. The reference implementation enforces ≤ 5 lamports per compute unit. + +4. Transfer intent and destination + +- The TransferChecked program MUST be either `spl-token` or `token-2022`. +- Destination MUST equal the Associated Token Account PDA for `(owner = payTo, mint = asset)` under the selected token program. + +5. Account existence + +- The `source` ATA MUST exist. +- The destination ATA MUST exist if and only if the Create ATA instruction is NOT present in the transaction. If Create ATA is present, the destination ATA MAY be absent prior to execution. + +6. Amount + +- The `amount` in TransferChecked MUST equal `maxAmountRequired` exactly. + +These checks are security-critical to ensure the fee payer cannot be tricked into transferring their own funds or sponsoring unintended actions. Implementations MAY introduce stricter limits (e.g., lower compute price caps) but MUST NOT relax the above constraints. diff --git a/specs/x402-specification.md b/specs/x402-specification.md index 62ec46899..e233489a4 100644 --- a/specs/x402-specification.md +++ b/specs/x402-specification.md @@ -218,7 +218,7 @@ Each scheme defines: - Settlement and validation procedures - Scheme-specific requirements in the `extra` field of `PaymentRequirements` -**6.1 Exact Scheme** +**6.1 Exact Scheme (EVM overview)** The "exact" scheme uses EIP-3009 (Transfer with Authorization) to enable secure, gasless transfers of specific amounts of ERC-20 tokens. @@ -254,6 +254,18 @@ 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 Exact Scheme (SVM overview)** + +For Solana (SVM), the `exact` scheme is implemented using `TransferChecked` for SPL tokens. Critical verification requirements include: + +- Enforcing a strict instruction layout (Compute Unit Limit, Compute Unit Price, optional ATA Create, TransferChecked) +- Ensuring the facilitator fee payer does not appear in any instruction accounts and is not the transfer `authority` or `source` +- Bounding compute unit price to mitigate gas abuse +- Verifying the destination ATA matches the `payTo`/`asset` PDA and account existence rules +- Requiring the transfer `amount` to exactly equal `maxAmountRequired` + +Full SVM details are specified in `specs/schemes/exact/scheme_exact_svm.md`. + **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. diff --git a/typescript/packages/a2a/TODO.md b/typescript/packages/a2a/TODO.md new file mode 100644 index 000000000..65b612e73 --- /dev/null +++ b/typescript/packages/a2a/TODO.md @@ -0,0 +1,14 @@ +# @x402/a2a + +## TODO + +The `@x402/a2a` package implements **x402 payment flows over the Agent-to-Agent (A2A) protocol**, enabling interoperable payments between agents across different transports and ecosystems. + +It builds on the `x402Client`, `x402Server`, and `x402Facilitator` abstractions, adapting them for A2A messaging and discovery patterns. + +This implementation allows x402-enabled agents to advertise, request, and settle payments as part of standard A2A communication flows. + +--- + +**Note:** The official A2A implementation currently exists in a separate repository. +The long-term goal is to **merge it into this repository** for unified development, testing, and release management. diff --git a/typescript/packages/x402-express/.prettierignore b/typescript/packages/core/.prettierignore similarity index 100% rename from typescript/packages/x402-express/.prettierignore rename to typescript/packages/core/.prettierignore diff --git a/typescript/packages/x402-express/.prettierrc b/typescript/packages/core/.prettierrc similarity index 100% rename from typescript/packages/x402-express/.prettierrc rename to typescript/packages/core/.prettierrc diff --git a/typescript/packages/core/README.md b/typescript/packages/core/README.md new file mode 100644 index 000000000..4817f1b62 --- /dev/null +++ b/typescript/packages/core/README.md @@ -0,0 +1,425 @@ +# @x402/core + +Core implementation of the x402 payment protocol for TypeScript/JavaScript applications. This package provides transport-agnostic client, server, and facilitator components for implementing 402 Payment Required responses with digital payments. + +## Installation + +```bash +npm install @x402/core +``` + +## Overview + +The x402 protocol enables micropayments for HTTP resources using cryptocurrency. This core package provides: + +- **Client Components**: For making payment-enabled requests +- **Server Components**: For protecting resources with payment requirements +- **Facilitator Integration**: For payment verification and settlement +- **HTTP Utilities**: For encoding/decoding payment headers +- **Type Definitions**: Full TypeScript support for v1 and v2 protocols + +## Features + +- šŸš€ **Protocol v2 Support**: Latest x402 protocol with header-based payments +- šŸ”„ **Backwards Compatible**: Full support for v1 protocol +- šŸŽÆ **Transport Agnostic**: Core logic separated from HTTP framework specifics +- šŸ”Œ **Extensible**: Register custom payment schemes and networks +- šŸ’¼ **Multi-Facilitator**: Support for multiple facilitator services +- šŸ“¦ **Type Safe**: Complete TypeScript definitions + +## Quick Start + +### Client Usage + +```typescript +import { x402HTTPClient } from '@x402/core/client'; +import { EVMExactScheme } from '@x402/evm'; // Implementation package + +// Create and configure client +const client = new x402HTTPClient(); + +// Register payment schemes for networks you support +client.registerScheme('eip155:8453', new EVMExactScheme({ + signer: wallet, // Your wallet/signer +})); + +// Make a payment-enabled request +const response = await fetch('https://api.example.com/protected', { + headers: { + ...otherHeaders, + } +}); + +if (response.status === 402) { + // Extract payment requirements + const paymentRequired = client.getPaymentRequiredResponse( + response.headers, + await response.json() + ); + + // Select and create payment + const requirements = client.selectPaymentRequirements( + paymentRequired.x402Version, + paymentRequired.accepts + ); + + const paymentPayload = await client.createPaymentPayload( + paymentRequired.x402Version, + requirements + ); + + // Retry with payment + const paidResponse = await fetch('https://api.example.com/protected', { + headers: { + ...otherHeaders, + ...client.encodePaymentSignatureHeader(paymentPayload), + } + }); + + // Get settlement confirmation + const settleResponse = client.getPaymentSettleResponse(paidResponse.headers); + console.log('Payment settled:', settleResponse.transaction); +} +``` + +### Server Usage + +```typescript +import { x402HTTPResourceService, HTTPFacilitatorClient } from '@x402/core/server'; +import { EVMExactScheme } from '@x402/evm'; + +// Configure routes with payment requirements +const routes = { + 'GET /api/data': { + scheme: 'exact', + network: 'eip155:8453', // Base network + payTo: '0xYourAddress', + price: '$0.01', // or { amount: '10000', asset: 'USDC' } + description: 'Premium data access', + mimeType: 'application/json', + }, + 'POST /api/*': { + scheme: 'exact', + network: 'eip155:8453', + payTo: '0xYourAddress', + price: '$0.05', + maxTimeoutSeconds: 600, + } +}; + +// Create server with facilitator +const facilitator = new HTTPFacilitatorClient({ + url: 'https://x402.org/facilitator', +}); + +const server = new x402HTTPResourceService(routes, facilitator); + +// Register supported schemes +server.registerScheme('eip155:8453', new EVMExactScheme()); + +// Initialize to fetch supported kinds from facilitator +await server.initialize(); + +// Process requests (framework-agnostic) +async function handleRequest(req: Request): Promise { + const context = { + adapter: createAdapter(req), // Your HTTP adapter + path: req.path, + method: req.method, + }; + + // Check if payment is required + const paymentResponse = await server.processHTTPRequest(context); + + if (paymentResponse) { + // Payment required - return 402 response + return new Response(paymentResponse.body, { + status: paymentResponse.status, + headers: paymentResponse.headers, + }); + } + + // Payment valid or not required - proceed with request + const response = await handleProtectedResource(req); + + // Process settlement after successful response + const settlementHeaders = await server.processSettlement(context, response.status); + + if (settlementHeaders) { + Object.entries(settlementHeaders).forEach(([key, value]) => { + response.headers.set(key, value); + }); + } + + return response; +} +``` + +### Facilitator Usage + +```typescript +import { x402Facilitator } from '@x402/core/facilitator'; +import { EVMExactFacilitator } from '@x402/evm'; + +// Create facilitator instance +const facilitator = new x402Facilitator(); + +// Register scheme implementations +facilitator.registerScheme('eip155:8453', new EVMExactFacilitator({ + rpcUrl: 'https://base.infura.io/v3/YOUR_KEY', +})); + +// Verify payment +const verifyResult = await facilitator.verify( + client, + paymentPayload, + paymentRequirements +); + +if (verifyResult.isValid) { + // Settle payment + const settleResult = await facilitator.settle( + signer, + paymentPayload, + paymentRequirements + ); + + console.log('Transaction:', settleResult.transaction); +} +``` + +## API Reference + +### Client Classes + +#### `x402Client` + +Base client for creating and managing payments. + +**Methods:** +- `registerScheme(network: Network, client: SchemeNetworkClient)`: Register a payment scheme +- `registerSchemeV1(network: Network, client: SchemeNetworkClient)`: Register v1 scheme +- `selectPaymentRequirements(x402Version: number, requirements: PaymentRequirements[])`: Choose payment method +- `createPaymentPayload(x402Version: number, requirements: PaymentRequirements)`: Create payment + +#### `x402HTTPClient` + +HTTP-specific client extending base client. + +**Methods:** +- `encodePaymentSignatureHeader(payload: PaymentPayload)`: Create payment header +- `getPaymentRequiredResponse(headers: Record, body?: PaymentRequired)`: Parse 402 response +- `getPaymentSettleResponse(headers: Record)`: Extract settlement info + +### Server Classes + +#### `x402ResourceService` + +Core server for protecting resources with payments. + +**Methods:** +- `registerScheme(network: Network, server: SchemeNetworkService)`: Register scheme handler +- `initialize()`: Fetch supported payment types from facilitators +- `buildPaymentRequirements(config: ResourceConfig)`: Create payment requirements +- `verifyPayment(payload: PaymentPayload, requirements: PaymentRequirements)`: Verify payment +- `settlePayment(payload: PaymentPayload, requirements: PaymentRequirements)`: Settle payment + +#### `x402HTTPResourceService` + +HTTP-enhanced server with routing and transport handling. + +**Constructor:** +```typescript +new x402HTTPResourceService( + routes: RoutesConfig, + facilitatorClients?: FacilitatorClient | FacilitatorClient[] +) +``` + +**Methods:** +- `processHTTPRequest(context: HTTPRequestContext, paywallConfig?: PaywallConfig)`: Handle HTTP request +- `processSettlement(context: HTTPRequestContext, responseStatus: number)`: Process settlement + +### Facilitator Classes + +#### `x402Facilitator` + +Local facilitator for payment verification and settlement. + +**Methods:** +- `registerScheme(network: Network, facilitator: SchemeNetworkFacilitator)`: Register handler +- `verify(client: any, payload: PaymentPayload, requirements: PaymentRequirements)`: Verify payment +- `settle(signer: any, payload: PaymentPayload, requirements: PaymentRequirements)`: Settle payment + +#### `HTTPFacilitatorClient` + +HTTP client for remote facilitator services. + +**Constructor:** +```typescript +new HTTPFacilitatorClient({ + url?: string, // Default: https://x402.org/facilitator + createAuthHeaders?: () => Promise +}) +``` + +### Types + +#### Core Types + +```typescript +type Network = `${string}:${string}`; // e.g., "eip155:8453" + +type Price = string | number | { + amount: string; + asset: string; + extra?: Record; +}; + +type PaymentRequirements = { + scheme: string; + network: Network; + asset: string; + amount: string; + payTo: string; + maxTimeoutSeconds: number; + extra: Record; +}; + +type PaymentPayload = { + x402Version: number; + scheme: string; + network: Network; + payload: Record; + accepted: PaymentRequirements; + extensions?: Record; +}; + +type PaymentRequired = { + x402Version: number; + error?: string; + resource: { + url: string; + description: string; + mimeType: string; + }; + accepts: PaymentRequirements[]; + extensions?: Record; +}; +``` + +#### Implementation Interfaces + +Implement these interfaces to add support for new payment schemes: + +```typescript +interface SchemeNetworkClient { + readonly scheme: string; + createPaymentPayload( + x402Version: number, + requirements: PaymentRequirements + ): Promise; +} + +interface SchemeNetworkService { + readonly scheme: string; + parsePrice(price: Price, network: Network): AssetAmount; + enhancePaymentRequirements( + requirements: PaymentRequirements, + supportedKind: any, + facilitatorExtensions: string[] + ): Promise; +} + +interface SchemeNetworkFacilitator { + readonly scheme: string; + verify( + client: any, + payload: PaymentPayload, + requirements: PaymentRequirements + ): Promise; + settle( + signer: any, + payload: PaymentPayload, + requirements: PaymentRequirements + ): Promise; +} +``` + +## HTTP Headers + +### v2 Protocol (Current) + +- `PAYMENT-SIGNATURE`: Base64-encoded payment payload +- `PAYMENT-REQUIRED`: Base64-encoded payment requirements +- `PAYMENT-RESPONSE`: Base64-encoded settlement response + +### v1 Protocol (Legacy) + +- `X-PAYMENT`: Base64-encoded payment payload +- `X-PAYMENT-RESPONSE`: Base64-encoded settlement response +- Payment requirements sent in response body + +## Utilities + +### HTTP Encoding/Decoding + +```typescript +import { + encodePaymentSignatureHeader, + decodePaymentSignatureHeader, + encodePaymentRequiredHeader, + decodePaymentRequiredHeader, + encodePaymentResponseHeader, + decodePaymentResponseHeader +} from '@x402/core/http'; +``` + +### Network Pattern Matching + +The package supports network pattern matching for multi-chain support: + +```typescript +// Register handler for all EIP-155 (EVM) networks +server.registerScheme('eip155:*', evmHandler); + +// Specific network takes precedence +server.registerScheme('eip155:8453', baseHandler); +``` + +## Framework Integration + +This core package is transport-agnostic. For framework-specific integrations, use: + +- `@x402/express` - Express.js middleware +- `@x402/hono` - Hono middleware +- `@x402/next` - Next.js integration +- `@x402/axios` - Axios interceptor +- `@x402/fetch` - Fetch wrapper + +## Implementation Packages + +For blockchain-specific implementations: + +- `@x402/evm` - Ethereum and EVM-compatible chains +- `@x402/solana` - Solana blockchain + +## Examples + +See the [examples directory](https://github.com/coinbase/x402/tree/main/examples) for complete examples including: + +- Basic client/server setup +- Multi-chain support +- Custom facilitator implementation +- Framework integrations +- Browser paywall UI + +## Contributing + +Contributions are welcome! Please see our [Contributing Guide](https://github.com/coinbase/x402/blob/main/CONTRIBUTING.md). + +## Support + +- [Documentation](https://x402.org/docs) +- [GitHub Issues](https://github.com/coinbase/x402/issues) +- [Discord Community](https://discord.gg/x402) diff --git a/typescript/packages/core/TODO.md b/typescript/packages/core/TODO.md new file mode 100644 index 000000000..2fa6f2f56 --- /dev/null +++ b/typescript/packages/core/TODO.md @@ -0,0 +1,91 @@ + + +# TODO + +## x402Client + +### Add policy based payment requirements filtering + +1. Add `addPolicy` function to `x402Client` +Allows the passing of a func that takes a payment requirement and returns true/false about whether the payment should be included or excluded + +```typescript +client + .addPolicy(paymentReq => paymentReq.maxAmountRequired <= 100_000) + .addPolicy(paymentReq => paymentReq.network !== "eip155:1") // no mainnet + .addPolicy((paymentReq, context) => context.timestamp > startTime); +``` + +*Note*: This does enable the package to export policy builder funcs that could assist in making lambda chaining more readeable +e.g. export + `blacklist(key: 'asset' | 'payTo' | 'network' | 'extra.${string}', values: string[]) => ((paymentReq: PaymentRequirement) => boolean)` + `whitelist(key: 'asset' | 'payTo' | 'network' | 'extra.${string}', values: string[]) => ((paymentReq: PaymentRequirements) => boolean)` + `matches(paymentReq: Partial) => ((paymentReq: PaymentRequirements) => boolean)` +and then you could have: +```typescript +client + .addPolicy(whitelist('asset', [ /* Tokens you actually hold in your wallet */])) + .addPolicy(whitelist('payTo', [ /* List of trusted vendors */])) +``` + +```typescript +client + .registerScheme('eip155:*', new ExactEvmClient(signer)) + .addPolicy(matches({ + network: `eip155:1`, + asset: '0x...', + })) + .addPolicy(whitelist('payTo', [ /* List of trusted vendors */])) +``` + +## x402HTTPResourceServer + +### Hooks + +A hooks system that powers the middleware allowing custom logic injection at critical payment flow points. Six hooks cover the entire payment lifecycle, with `onSettlementFailure` being the most critical for handling irreversible side effects. + +```typescript +paymentMiddleware(payTo, routes, facilitator, { + beforeVerification: async ({ requirements, payload, request }) => {}, + afterVerification: async ({ requirements, payload, request }) => {}, + beforeSettlement: async ({ requirements, payload, request }) => {}, + afterSettlement: async ({ requirements, payload, request, response }) => {}, + onSettlementFailure: async ({ requirements, payload, request, response }) => {}, + onVerificationFailure: async ({ requirements, payload, request, response }) => {} +}); +``` + +### Dynamic Pricing in RouteConfig + +Price to be a callback function that determines pricing at runtime based on request context. + +```typescript +{ + "/api/data": { + price: async (request) => { + const tier = request.query.tier; + return tier === "premium" ? "$0.10" : "$0.01"; + }, + payTo: "0x209693Bc6afc0C5329bA36FaF03C514EF312287C", + network: "eip155:84532" + } +} +``` + +### Dynamic PayTo in RouteConfig + +The `payTo` parameter to be a callback function that determines the payment recipient at runtime based on request context. + +```typescript +{ + "/api/data": { + payTo: async (request) => { + const productId = request.body.productId; + const sellerAddress = await getSellerAddress(productId); + return sellerAddress; // Returns address string + }, + price: "$0.10", + network: "eip155:84532" + } +} +``` \ No newline at end of file diff --git a/typescript/packages/x402/eslint.config.js b/typescript/packages/core/eslint.config.js similarity index 100% rename from typescript/packages/x402/eslint.config.js rename to typescript/packages/core/eslint.config.js diff --git a/typescript/packages/core/package.json b/typescript/packages/core/package.json new file mode 100644 index 000000000..78453cdbe --- /dev/null +++ b/typescript/packages/core/package.json @@ -0,0 +1,128 @@ +{ + "name": "@x402/core", + "version": "0.7.0", + "main": "./dist/cjs/index.js", + "module": "./dist/esm/index.js", + "types": "./dist/cjs/index.d.ts", + "scripts": { + "start": "tsx --env-file=.env index.ts", + "build": "tsup", + "test": "vitest run", + "test:watch": "vitest", + "watch": "tsc --watch", + "format": "prettier -c .prettierrc --write \"**/*.{ts,js,cjs,json,md}\"", + "format:check": "prettier -c .prettierrc --check \"**/*.{ts,js,cjs,json,md}\"", + "lint": "eslint . --ext .ts --fix", + "lint:check": "eslint . --ext .ts" + }, + "keywords": [], + "license": "Apache-2.0", + "author": "Coinbase Inc.", + "repository": "https://github.com/coinbase/x402", + "description": "x402 Payment Protocol", + "devDependencies": { + "@eslint/js": "^9.24.0", + "@types/node": "^22.13.4", + "@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", + "tsup": "^8.4.0", + "tsx": "^4.19.2", + "typescript": "^5.7.3", + "vite": "^6.2.6", + "vite-tsconfig-paths": "^5.1.4", + "vitest": "^3.0.5" + }, + "dependencies": { + "zod": "^3.24.2" + }, + "exports": { + ".": { + "import": { + "types": "./dist/esm/index.d.mts", + "default": "./dist/esm/index.mjs" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + } + }, + "./client": { + "import": { + "types": "./dist/esm/client/index.d.mts", + "default": "./dist/esm/client/index.mjs" + }, + "require": { + "types": "./dist/cjs/client/index.d.ts", + "default": "./dist/cjs/client/index.js" + } + }, + "./facilitator": { + "import": { + "types": "./dist/esm/facilitator/index.d.mts", + "default": "./dist/esm/facilitator/index.mjs" + }, + "require": { + "types": "./dist/cjs/facilitator/index.d.ts", + "default": "./dist/cjs/facilitator/index.js" + } + }, + "./http": { + "import": { + "types": "./dist/esm/http/index.d.mts", + "default": "./dist/esm/http/index.mjs" + }, + "require": { + "types": "./dist/cjs/http/index.d.ts", + "default": "./dist/cjs/http/index.js" + } + }, + "./server": { + "import": { + "types": "./dist/esm/server/index.d.mts", + "default": "./dist/esm/server/index.mjs" + }, + "require": { + "types": "./dist/cjs/server/index.d.ts", + "default": "./dist/cjs/server/index.js" + } + }, + "./types": { + "import": { + "types": "./dist/esm/types/index.d.mts", + "default": "./dist/esm/types/index.mjs" + }, + "require": { + "types": "./dist/cjs/types/index.d.ts", + "default": "./dist/cjs/types/index.js" + } + }, + "./types/v1": { + "import": { + "types": "./dist/esm/types/v1/index.d.mts", + "default": "./dist/esm/types/v1/index.mjs" + }, + "require": { + "types": "./dist/cjs/types/v1/index.d.ts", + "default": "./dist/cjs/types/v1/index.js" + } + }, + "./utils": { + "import": { + "types": "./dist/esm/utils/index.d.mts", + "default": "./dist/esm/utils/index.mjs" + }, + "require": { + "types": "./dist/cjs/utils/index.d.ts", + "default": "./dist/cjs/utils/index.js" + } + } + }, + "files": [ + "dist" + ] +} diff --git a/typescript/packages/core/src/client/index.ts b/typescript/packages/core/src/client/index.ts new file mode 100644 index 000000000..593c3e891 --- /dev/null +++ b/typescript/packages/core/src/client/index.ts @@ -0,0 +1,2 @@ +export * from "./x402Client"; +export * from "../http/x402HTTPClient"; \ No newline at end of file diff --git a/typescript/packages/core/src/client/x402Client.ts b/typescript/packages/core/src/client/x402Client.ts new file mode 100644 index 000000000..97a853ec5 --- /dev/null +++ b/typescript/packages/core/src/client/x402Client.ts @@ -0,0 +1,139 @@ +import { x402Version } from ".."; +import { SchemeNetworkClient } from "../types/mechanisms"; +import { PaymentPayload, PaymentRequirements } from "../types/payments"; +import { Network } from "../types"; +import { findByNetworkAndScheme, findSchemesByNetwork } from "../utils"; + +export type SelectPaymentRequirements = (x402Version: number, paymentRequirements: PaymentRequirements[]) => PaymentRequirements; + +/** + * + */ +export class x402Client { + private readonly paymentRequirementsSelector: SelectPaymentRequirements; + private readonly registeredClientSchemes: Map>> = new Map(); + + /** + * Creates a new x402Client instance. + * + * @param paymentRequirementsSelector - Function to select payment requirements from available options + */ + constructor(paymentRequirementsSelector?: SelectPaymentRequirements) { + this.paymentRequirementsSelector = paymentRequirementsSelector || ((x402Version, accepts) => accepts[0]); + } + + /** + * Registers a scheme client for the current x402 version. + * + * @param network - The network to register the client for + * @param client - The scheme network client to register + * @returns The x402Client instance for chaining + */ + registerScheme(network: Network, client: SchemeNetworkClient): x402Client { + return this._registerScheme(x402Version, network, client); + } + + /** + * Registers a scheme client for x402 version 1. + * + * @param network - The network to register the client for + * @param client - The scheme network client to register + * @returns The x402Client instance for chaining + */ + registerSchemeV1(network: Network, client: SchemeNetworkClient): x402Client { + return this._registerScheme(1, network, client); + } + + /** + * Selects appropriate payment requirements based on registered clients. + * + * @param x402Version - The x402 protocol version + * @param paymentRequirements - Array of available payment requirements + * @returns The selected payment requirements + */ + selectPaymentRequirements(x402Version: number, paymentRequirements: PaymentRequirements[]): PaymentRequirements { + const clientSchemesByNetwork = this.registeredClientSchemes.get(x402Version); + if (!clientSchemesByNetwork) { + throw new Error(`No client registered for x402 version: ${x402Version}`); + } + + const supportedPaymentRequirements = paymentRequirements.filter(requirement => { + let clientSchemes = findSchemesByNetwork(clientSchemesByNetwork, requirement.network); + if (!clientSchemes) { + return false; + } + + return clientSchemes.has(requirement.scheme); + }) + + if (supportedPaymentRequirements.length === 0) { + throw new Error(`No network/scheme registered for x402 version: ${x402Version} which comply with the payment requirements. ${JSON.stringify({ + x402Version, + paymentRequirements, + x402Versions: Array.from(this.registeredClientSchemes.keys()), + networks: Array.from(clientSchemesByNetwork.keys()), + schemes: Array.from(clientSchemesByNetwork.values()).map(schemes => Array.from(schemes.keys())).flat(), + })}`); + } + + return this.paymentRequirementsSelector(x402Version, supportedPaymentRequirements); + } + + /** + * Creates a payment payload based on the requirements. + * + * @param x402Version - The x402 protocol version + * @param requirements - The payment requirements + * @param extensions - Optional extensions to include in the payload (from PaymentRequired) + * @returns Promise resolving to the payment payload + */ + async createPaymentPayload( + x402Version: number, + requirements: PaymentRequirements, + extensions?: Record + ): Promise { + const clientSchemesByNetwork = this.registeredClientSchemes.get(x402Version); + if (!clientSchemesByNetwork) { + throw new Error(`No client registered for x402 version: ${x402Version}`); + } + + const schemeNetworkClient = findByNetworkAndScheme(clientSchemesByNetwork, requirements.scheme, requirements.network); + if (schemeNetworkClient) { + const payload = await schemeNetworkClient.createPaymentPayload(x402Version, requirements); + + // Copy extensions from PaymentRequired into PaymentPayload + if (extensions && Object.keys(extensions).length > 0) { + payload.extensions = extensions; + } + + return payload; + } + + throw new Error(`No client registered for scheme: ${requirements.scheme} and network: ${requirements.network}`); + } + + /** + * Internal method to register a scheme client. + * + * @param x402Version - The x402 protocol version + * @param network - The network to register the client for + * @param client - The scheme network client to register + * @returns The x402Client instance for chaining + */ + private _registerScheme(x402Version: number, network: Network, client: SchemeNetworkClient): x402Client { + if (!this.registeredClientSchemes.has(x402Version)) { + this.registeredClientSchemes.set(x402Version, new Map()); + } + const clientSchemesByNetwork = this.registeredClientSchemes.get(x402Version)!; + if (!clientSchemesByNetwork.has(network)) { + clientSchemesByNetwork.set(network, new Map()); + } + + const clientByScheme = clientSchemesByNetwork.get(network)!; + if (!clientByScheme.has(client.scheme)) { + clientByScheme.set(client.scheme, client); + } + + return this; + } +} \ No newline at end of file diff --git a/typescript/packages/core/src/facilitator/index.ts b/typescript/packages/core/src/facilitator/index.ts new file mode 100644 index 000000000..d1409c99a --- /dev/null +++ b/typescript/packages/core/src/facilitator/index.ts @@ -0,0 +1 @@ +export * from "./x402Facilitator"; diff --git a/typescript/packages/core/src/facilitator/x402Facilitator.ts b/typescript/packages/core/src/facilitator/x402Facilitator.ts new file mode 100644 index 000000000..77b57f06a --- /dev/null +++ b/typescript/packages/core/src/facilitator/x402Facilitator.ts @@ -0,0 +1,155 @@ +import { x402Version } from ".."; +import { SettleResponse, VerifyResponse } from "../types/facilitator"; +import { SchemeNetworkFacilitator } from "../types/mechanisms"; +import { PaymentPayload, PaymentRequirements } from "../types/payments"; +import { Network } from "../types"; +import { findByNetworkAndScheme } from "../utils"; + +/** + * + */ +export class x402Facilitator { + // Mapping: x402Version -> network / pattern -> scheme -> SchemeNetworkFacilitator + private readonly registeredFacilitatorSchemes: Map< + number, + Map> + > = new Map(); + + // Extensions this facilitator supports (e.g., "bazaar", "sign_in_with_x") + private readonly extensions: string[] = []; + + /** + * Registers a scheme facilitator for the current x402 version. + * + * @param network - The network to register the facilitator for + * @param facilitator - The scheme network facilitator to register + * @returns The x402Facilitator instance for chaining + */ + registerScheme(network: Network, facilitator: SchemeNetworkFacilitator): x402Facilitator { + return this._registerScheme(x402Version, network, facilitator); + } + + /** + * Registers a scheme facilitator for x402 version 1. + * + * @param network - The network to register the facilitator for + * @param facilitator - The scheme network facilitator to register + * @returns The x402Facilitator instance for chaining + */ + registerSchemeV1(network: Network, facilitator: SchemeNetworkFacilitator): x402Facilitator { + return this._registerScheme(1, network, facilitator); + } + + /** + * Registers a protocol extension. + * + * @param extension - The extension name to register (e.g., "bazaar", "sign_in_with_x") + * @returns The x402Facilitator instance for chaining + */ + registerExtension(extension: string): x402Facilitator { + // Check if already registered + if (!this.extensions.includes(extension)) { + this.extensions.push(extension); + } + return this; + } + + /** + * Gets the list of registered extensions. + * + * @returns Array of extension names + */ + getExtensions(): string[] { + return [...this.extensions]; + } + + /** + * Verifies a payment payload against requirements. + * + * @param paymentPayload - The payment payload to verify + * @param paymentRequirements - The payment requirements to verify against + * @returns Promise resolving to the verification response + */ + verify( + paymentPayload: PaymentPayload, + paymentRequirements: PaymentRequirements, + ): Promise { + const facilitatorSchemesByNetwork = this.registeredFacilitatorSchemes.get( + paymentPayload.x402Version, + ); + if (!facilitatorSchemesByNetwork) { + throw new Error(`No facilitator registered for x402 version: ${paymentPayload.x402Version}`); + } + + const schemeNetworkFacilitator = findByNetworkAndScheme( + facilitatorSchemesByNetwork, + paymentRequirements.scheme, + paymentRequirements.network, + ); + if (schemeNetworkFacilitator) { + return schemeNetworkFacilitator.verify(paymentPayload, paymentRequirements); + } + + throw new Error( + `No facilitator registered for scheme: ${paymentRequirements.scheme} and network: ${paymentRequirements.network}`, + ); + } + + /** + * Settles a payment based on the payload and requirements. + * + * @param paymentPayload - The payment payload to settle + * @param paymentRequirements - The payment requirements for settlement + * @returns Promise resolving to the settlement response + */ + settle( + paymentPayload: PaymentPayload, + paymentRequirements: PaymentRequirements, + ): Promise { + const facilitatorSchemesByNetwork = this.registeredFacilitatorSchemes.get( + paymentPayload.x402Version, + ); + if (!facilitatorSchemesByNetwork) { + throw new Error(`No facilitator registered for x402 version: ${paymentPayload.x402Version}`); + } + + const schemeNetworkFacilitator = findByNetworkAndScheme( + facilitatorSchemesByNetwork, + paymentRequirements.scheme, + paymentRequirements.network, + ); + if (schemeNetworkFacilitator) { + return schemeNetworkFacilitator.settle(paymentPayload, paymentRequirements); + } + throw new Error( + `No facilitator registered for scheme: ${paymentRequirements.scheme} and network: ${paymentRequirements.network}`, + ); + } + + /** + * Internal method to register a scheme facilitator. + * + * @param x402Version - The x402 protocol version + * @param network - The network to register the facilitator for + * @param facilitator - The scheme network facilitator to register + * @returns The x402Facilitator instance for chaining + */ + private _registerScheme( + x402Version: number, + network: Network, + facilitator: SchemeNetworkFacilitator, + ): x402Facilitator { + if (!this.registeredFacilitatorSchemes.has(x402Version)) { + this.registeredFacilitatorSchemes.set(x402Version, new Map()); + } + const networkFacilitatorSchemes = this.registeredFacilitatorSchemes.get(x402Version)!; + if (!networkFacilitatorSchemes.has(network)) { + networkFacilitatorSchemes.set(network, new Map()); + } + const facilitatorByScheme = networkFacilitatorSchemes.get(network)!; + if (!facilitatorByScheme.has(facilitator.scheme)) { + facilitatorByScheme.set(facilitator.scheme, facilitator); + } + return this; + } +} diff --git a/typescript/packages/core/src/http/httpFacilitatorClient.ts b/typescript/packages/core/src/http/httpFacilitatorClient.ts new file mode 100644 index 000000000..64550b769 --- /dev/null +++ b/typescript/packages/core/src/http/httpFacilitatorClient.ts @@ -0,0 +1,186 @@ +import { PaymentPayload, PaymentRequirements } from "../types/payments"; +import { VerifyResponse, SettleResponse, SupportedResponse } from "../types/facilitator"; + +const DEFAULT_FACILITATOR_URL = "https://x402.org/facilitator"; + +export interface FacilitatorConfig { + url?: string; + createAuthHeaders?: () => Promise<{ + verify: Record; + settle: Record; + supported: Record; + }>; +} + +/** + * Interface for facilitator clients + * Can be implemented for HTTP-based or local facilitators + */ +export interface FacilitatorClient { + /** + * Verify a payment with the facilitator + * + * @param paymentPayload - The payment to verify + * @param paymentRequirements - The requirements to verify against + * @returns Verification response + */ + verify( + paymentPayload: PaymentPayload, + paymentRequirements: PaymentRequirements, + ): Promise; + + /** + * Settle a payment with the facilitator + * + * @param paymentPayload - The payment to settle + * @param paymentRequirements - The requirements for settlement + * @returns Settlement response + */ + settle( + paymentPayload: PaymentPayload, + paymentRequirements: PaymentRequirements, + ): Promise; + + /** + * Get supported payment kinds and extensions from the facilitator + * + * @returns Supported payment kinds and extensions + */ + getSupported(): Promise; +} + +/** + * HTTP-based client for interacting with x402 facilitator services + * Handles HTTP communication with facilitator endpoints + */ +export class HTTPFacilitatorClient implements FacilitatorClient { + private readonly url: string; + private readonly createAuthHeaders?: FacilitatorConfig["createAuthHeaders"]; + + /** + * Creates a new HTTPFacilitatorClient instance. + * + * @param config - Configuration options for the facilitator client + */ + constructor(config?: FacilitatorConfig) { + this.url = config?.url || DEFAULT_FACILITATOR_URL; + this.createAuthHeaders = config?.createAuthHeaders; + } + + /** + * Verify a payment with the facilitator + * + * @param paymentPayload - The payment to verify + * @param paymentRequirements - The requirements to verify against + * @returns Verification response + */ + async verify( + paymentPayload: PaymentPayload, + paymentRequirements: PaymentRequirements, + ): Promise { + let headers: Record = { + "Content-Type": "application/json", + }; + + if (this.createAuthHeaders) { + const authHeaders = await this.createAuthHeaders(); + headers = { ...headers, ...authHeaders.verify }; + } + + const response = await fetch(`${this.url}/verify`, { + method: "POST", + headers, + body: JSON.stringify({ + x402Version: paymentPayload.x402Version, + paymentPayload: this.toJsonSafe(paymentPayload), + paymentRequirements: this.toJsonSafe(paymentRequirements), + }), + }); + + if (!response.ok) { + const errorText = await response.text().catch(() => response.statusText); + throw new Error(`Facilitator verify failed (${response.status}): ${errorText}`); + } + + return (await response.json()) as VerifyResponse; + } + + /** + * Settle a payment with the facilitator + * + * @param paymentPayload - The payment to settle + * @param paymentRequirements - The requirements for settlement + * @returns Settlement response + */ + async settle( + paymentPayload: PaymentPayload, + paymentRequirements: PaymentRequirements, + ): Promise { + let headers: Record = { + "Content-Type": "application/json", + }; + + if (this.createAuthHeaders) { + const authHeaders = await this.createAuthHeaders(); + headers = { ...headers, ...authHeaders.settle }; + } + + const response = await fetch(`${this.url}/settle`, { + method: "POST", + headers, + body: JSON.stringify({ + x402Version: paymentPayload.x402Version, + paymentPayload: this.toJsonSafe(paymentPayload), + paymentRequirements: this.toJsonSafe(paymentRequirements), + }), + }); + + if (!response.ok) { + const errorText = await response.text().catch(() => response.statusText); + throw new Error(`Facilitator settle failed (${response.status}): ${errorText}`); + } + + return (await response.json()) as SettleResponse; + } + + /** + * Get supported payment kinds and extensions from the facilitator + * + * @returns Supported payment kinds and extensions + */ + async getSupported(): Promise { + let headers: Record = { + "Content-Type": "application/json", + }; + + if (this.createAuthHeaders) { + const authHeaders = await this.createAuthHeaders(); + headers = { ...headers, ...authHeaders.supported }; + } + + const response = await fetch(`${this.url}/supported`, { + method: "GET", + headers, + }); + + if (!response.ok) { + const errorText = await response.text().catch(() => response.statusText); + throw new Error(`Facilitator getSupported failed (${response.status}): ${errorText}`); + } + + return (await response.json()) as SupportedResponse; + } + + /** + * Helper to convert objects to JSON-safe format. + * Handles BigInt and other non-JSON types. + * + * @param obj - The object to convert + * @returns The JSON-safe representation of the object + */ + private toJsonSafe(obj: unknown): unknown { + return JSON.parse( + JSON.stringify(obj, (_, value) => (typeof value === "bigint" ? value.toString() : value)), + ); + } +} diff --git a/typescript/packages/core/src/http/index.ts b/typescript/packages/core/src/http/index.ts new file mode 100644 index 000000000..b5ece3c8b --- /dev/null +++ b/typescript/packages/core/src/http/index.ts @@ -0,0 +1,94 @@ +import { SettleResponse } from "../types"; +import { PaymentPayload, PaymentRequired } from "../types/payments"; +import { Base64EncodedRegex, safeBase64Decode, safeBase64Encode } from "../utils"; + +// HTTP Methods that typically use query parameters +export type QueryParamMethods = "GET" | "HEAD" | "DELETE"; + +// HTTP Methods that typically use request body +export type BodyMethods = "POST" | "PUT" | "PATCH"; + +/** + * Encodes a payment payload as a base64 header value. + * + * @param paymentPayload - The payment payload to encode + * @returns Base64 encoded string representation of the payment payload + */ +export function encodePaymentSignatureHeader(paymentPayload: PaymentPayload): string { + return safeBase64Encode(JSON.stringify(paymentPayload)); +} + +/** + * Decodes a base64 payment signature header into a payment payload. + * + * @param paymentSignatureHeader - The base64 encoded payment signature header + * @returns The decoded payment payload + */ +export function decodePaymentSignatureHeader(paymentSignatureHeader: string): PaymentPayload { + if (!Base64EncodedRegex.test(paymentSignatureHeader)) { + throw new Error("Invalid payment signature header"); + } + return JSON.parse(safeBase64Decode(paymentSignatureHeader)) as PaymentPayload; +} + +/** + * Encodes a payment required object as a base64 header value. + * + * @param paymentRequired - The payment required object to encode + * @returns Base64 encoded string representation of the payment required object + */ +export function encodePaymentRequiredHeader(paymentRequired: PaymentRequired): string { + return safeBase64Encode(JSON.stringify(paymentRequired)); +} + +/** + * Decodes a base64 payment required header into a payment required object. + * + * @param paymentRequiredHeader - The base64 encoded payment required header + * @returns The decoded payment required object + */ +export function decodePaymentRequiredHeader(paymentRequiredHeader: string): PaymentRequired { + if (!Base64EncodedRegex.test(paymentRequiredHeader)) { + throw new Error("Invalid payment required header"); + } + return JSON.parse(safeBase64Decode(paymentRequiredHeader)) as PaymentRequired; +} + +/** + * Encodes a payment response as a base64 header value. + * + * @param paymentResponse - The payment response to encode + * @returns Base64 encoded string representation of the payment response + */ +export function encodePaymentResponseHeader(paymentResponse: SettleResponse): string { + return safeBase64Encode(JSON.stringify(paymentResponse)); +} + +/** + * Decodes a base64 payment response header into a settle response. + * + * @param paymentResponseHeader - The base64 encoded payment response header + * @returns The decoded settle response + */ +export function decodePaymentResponseHeader(paymentResponseHeader: string): SettleResponse { + if (!Base64EncodedRegex.test(paymentResponseHeader)) { + throw new Error("Invalid payment response header"); + } + return JSON.parse(safeBase64Decode(paymentResponseHeader)) as SettleResponse; +} + +// Export HTTP service and types +export { + x402HTTPResourceService, + HTTPAdapter, + HTTPRequestContext, + HTTPResponseInstructions, + HTTPProcessResult, + PaywallConfig, + PaywallProvider, + RouteConfig, + RoutesConfig, + CompiledRoute, +} from "./x402HTTPResourceService"; +export { HTTPFacilitatorClient } from "./httpFacilitatorClient"; +export { x402HTTPClient } from "./x402HTTPClient"; diff --git a/typescript/packages/core/src/http/middleware-example.ts b/typescript/packages/core/src/http/middleware-example.ts new file mode 100644 index 000000000..e69de29bb diff --git a/typescript/packages/core/src/http/x402HTTPClient.ts b/typescript/packages/core/src/http/x402HTTPClient.ts new file mode 100644 index 000000000..3f7111b48 --- /dev/null +++ b/typescript/packages/core/src/http/x402HTTPClient.ts @@ -0,0 +1,82 @@ +import { + decodePaymentRequiredHeader, + decodePaymentResponseHeader, + encodePaymentSignatureHeader, +} from "."; +import { SettleResponse } from "../types"; +import { PaymentPayload, PaymentRequired } from "../types/payments"; +import { x402Client } from "../client/x402Client"; + +/** + * + */ +export class x402HTTPClient extends x402Client { + /** + * Encodes a payment payload into appropriate HTTP headers based on version. + * + * @param paymentPayload - The payment payload to encode + * @returns HTTP headers containing the encoded payment signature + */ + encodePaymentSignatureHeader(paymentPayload: PaymentPayload): Record { + switch (paymentPayload.x402Version) { + case 2: + return { + "PAYMENT-SIGNATURE": encodePaymentSignatureHeader(paymentPayload), + }; + case 1: + return { + "X-PAYMENT": encodePaymentSignatureHeader(paymentPayload), + }; + default: + throw new Error( + `Unsupported x402 version: ${(paymentPayload as PaymentPayload).x402Version}`, + ); + } + } + + /** + * Extracts payment required information from HTTP response. + * + * @param headers - The HTTP response headers + * @param body - Optional response body for v1 compatibility + * @returns The payment required object + */ + getPaymentRequiredResponse(headers: Record, body?: unknown): PaymentRequired { + // v2 + if (headers["PAYMENT-REQUIRED"]) { + return decodePaymentRequiredHeader(headers["PAYMENT-REQUIRED"]); + } + + // v1 + if ( + body && + body instanceof Object && + "x402Version" in body && + (body as PaymentRequired).x402Version === 1 + ) { + return body as PaymentRequired; + } + + throw new Error("Invalid payment required response"); + } + + /** + * Extracts payment settlement response from HTTP headers. + * + * @param headers - The HTTP response headers + * @returns The settlement response object + */ + getPaymentSettleResponse(headers: Record): SettleResponse { + // v2 + if (headers["PAYMENT-RESPONSE"]) { + return decodePaymentResponseHeader(headers["PAYMENT-RESPONSE"]); + } + + // v1 + if (headers["X-PAYMENT-RESPONSE"]) { + return decodePaymentResponseHeader(headers["X-PAYMENT-RESPONSE"]); + } + + throw new Error("Payment response header not found"); + } +} diff --git a/typescript/packages/core/src/http/x402HTTPResourceService.ts b/typescript/packages/core/src/http/x402HTTPResourceService.ts new file mode 100644 index 000000000..bd707be14 --- /dev/null +++ b/typescript/packages/core/src/http/x402HTTPResourceService.ts @@ -0,0 +1,555 @@ +import { FacilitatorClient, x402ResourceService } from "../server"; +import { + decodePaymentSignatureHeader, + encodePaymentRequiredHeader, + encodePaymentResponseHeader, +} from "."; +import { + PaymentPayload, + PaymentRequired, + SettleResponse, + Price, + Network, + PaymentRequirements, +} from "../types"; + +/** + * Framework-agnostic HTTP adapter interface + * Implementations provide framework-specific HTTP operations + */ +export interface HTTPAdapter { + getHeader(name: string): string | undefined; + getMethod(): string; + getPath(): string; + getUrl(): string; + getAcceptHeader(): string; + getUserAgent(): string; +} + +/** + * Paywall configuration for HTML responses + */ +export interface PaywallConfig { + cdpClientKey?: string; + appName?: string; + appLogo?: string; + sessionTokenEndpoint?: string; + currentUrl?: string; + testnet?: boolean; +} + +/** + * Paywall provider interface for generating HTML + */ +export interface PaywallProvider { + generateHtml(paymentRequired: PaymentRequired, config?: PaywallConfig): string; +} + +/** + * Route configuration for HTTP endpoints + */ +export interface RouteConfig { + scheme: string; + payTo: string; + price: Price; + network: Network; + maxTimeoutSeconds?: number; + extra?: Record; + + // HTTP-specific metadata + resource?: string; + description?: string; + mimeType?: string; + customPaywallHtml?: string; + discoverable?: boolean; + inputSchema?: unknown; + outputSchema?: unknown; + + // Extensions + extensions?: Record; +} + +/** + * Routes configuration - maps path patterns to route configs + */ +export type RoutesConfig = Record | RouteConfig; + +/** + * Compiled route for efficient matching + */ +export interface CompiledRoute { + verb: string; + regex: RegExp; + config: RouteConfig; +} + +/** + * HTTP request context that encapsulates all request data + */ +export interface HTTPRequestContext { + adapter: HTTPAdapter; + path: string; + method: string; + paymentHeader?: string; +} + +/** + * HTTP response instructions for the framework middleware + */ +export interface HTTPResponseInstructions { + status: number; + headers: Record; + body?: unknown; // e.g. Paywall for web browser requests, but could be any other type + isHtml?: boolean; // e.g. if body is a paywall, then isHtml is true +} + +/** + * Result of processing an HTTP request for payment + */ +export type HTTPProcessResult = + | { type: "no-payment-required" } + | { + type: "payment-verified"; + paymentPayload: PaymentPayload; + paymentRequirements: PaymentRequirements; + } + | { type: "payment-error"; response: HTTPResponseInstructions }; + +/** + * HTTP-enhanced x402 resource server + * Provides framework-agnostic HTTP protocol handling + */ +export class x402HTTPResourceService extends x402ResourceService { + private compiledRoutes: CompiledRoute[] = []; + private paywallProvider?: PaywallProvider; + + /** + * Creates a new x402HTTPResourceService instance. + * + * @param routes - Route configuration for payment-protected endpoints + * @param facilitatorClients - Optional facilitator client(s) for payment processing + */ + constructor(routes: RoutesConfig, facilitatorClients?: FacilitatorClient | FacilitatorClient[]) { + super(facilitatorClients); + + // Handle both single route and multiple routes + const normalizedRoutes = + typeof routes === "object" && !("scheme" in routes) + ? (routes as Record) + : { "*": routes as RouteConfig }; + + for (const [pattern, config] of Object.entries(normalizedRoutes)) { + const parsed = this.parseRoutePattern(pattern); + this.compiledRoutes.push({ + verb: parsed.verb, + regex: parsed.regex, + config, + }); + } + } + + /** + * Register a custom paywall provider for generating HTML. If no provider is provided, the default paywall provider will be used. + * + * @param provider - Optional PaywallProvider instance + * @returns This service instance for chaining + */ + registerPaywallProvider(provider?: PaywallProvider): this { + this.paywallProvider = provider; + return this; // typing `this` instead of `x402HTTPResourceService` allows for extending the service class + } + + /** + * Process HTTP request and return response instructions + * This is the main entry point for framework middleware + * + * @param context - HTTP request context + * @param paywallConfig - Optional paywall configuration + * @returns Process result indicating next action for middleware + */ + async processHTTPRequest( + context: HTTPRequestContext, + paywallConfig?: PaywallConfig, + ): Promise { + const { adapter, path, method } = context; + + // Find matching route + const routeConfig = this.getRouteConfig(path, method); + if (!routeConfig) { + return { type: "no-payment-required" }; // No payment required for this route + } + + // Check for payment header (v1 or v2) + const paymentPayload = this.extractPayment(adapter); + + // Create resource info first + const resourceInfo = { + url: context.adapter.getUrl(), + description: routeConfig.description || "", + mimeType: routeConfig.mimeType || "", + }; + + // Build payment requirements from route config + const requirements = await this.buildPaymentRequirements(routeConfig); + + // Add resource URL to all payment requirements for discovery + requirements.forEach(req => { + if (!req.extra) { + req.extra = {}; + } + req.extra.resourceUrl = resourceInfo.url; + }); + + const paymentRequired = this.createPaymentRequiredResponse( + requirements, + resourceInfo, + !paymentPayload ? "Payment required" : undefined, + routeConfig.extensions, + ); + + // If no payment provided + if (!paymentPayload) { + return { + type: "payment-error", + response: this.createHTTPResponse( + paymentRequired, + this.isWebBrowser(adapter), + paywallConfig, + routeConfig.customPaywallHtml, + ), + }; + } + + // Verify payment + try { + const matchingRequirements = this.findMatchingRequirements( + paymentRequired.accepts, + paymentPayload, + ); + + if (!matchingRequirements) { + const errorResponse = this.createPaymentRequiredResponse( + requirements, + resourceInfo, + "No matching payment requirements", + routeConfig.extensions, + ); + return { + type: "payment-error", + response: this.createHTTPResponse(errorResponse, false, paywallConfig), + }; + } + + const verifyResult = await this.verifyPayment(paymentPayload, matchingRequirements); + + if (!verifyResult.isValid) { + const errorResponse = this.createPaymentRequiredResponse( + requirements, + resourceInfo, + verifyResult.invalidReason, + routeConfig.extensions, + ); + return { + type: "payment-error", + response: this.createHTTPResponse(errorResponse, false, paywallConfig), + }; + } + + // Payment is valid, return data needed for settlement + return { + type: "payment-verified", + paymentPayload, + paymentRequirements: matchingRequirements, + }; + } catch (error) { + const errorResponse = this.createPaymentRequiredResponse( + requirements, + resourceInfo, + error instanceof Error ? error.message : "Payment verification failed", + routeConfig.extensions, + ); + return { + type: "payment-error", + response: this.createHTTPResponse(errorResponse, false, paywallConfig), + }; + } + } + + /** + * Process settlement after successful response + * + * @param paymentPayload - The verified payment payload + * @param requirements - The matching payment requirements + * @param responseStatus - Status code from protected resource + * @returns Settlement response headers or null + */ + async processSettlement( + paymentPayload: PaymentPayload, + requirements: PaymentRequirements, + responseStatus: number, + ): Promise | null> { + // Don't settle if response failed + if (responseStatus >= 400) { + return null; + } + + try { + const settleResult = await this.settlePayment(paymentPayload, requirements); + return this.createSettlementHeaders(settleResult); + } catch (error) { + console.error("Settlement failed:", error); + throw error; + } + } + + /** + * Get route configuration for a request + * + * @param path - Request path + * @param method - HTTP method + * @returns Route configuration or undefined if no match + */ + private getRouteConfig(path: string, method: string): RouteConfig | undefined { + const normalizedPath = this.normalizePath(path); + const upperMethod = method.toUpperCase(); + + const matchingRoute = this.compiledRoutes.find( + route => + route.regex.test(normalizedPath) && (route.verb === "*" || route.verb === upperMethod), + ); + + return matchingRoute?.config; + } + + /** + * Extract payment from HTTP headers (handles v1 and v2) + * + * @param adapter - HTTP adapter + * @returns Decoded payment payload or null + */ + private extractPayment(adapter: HTTPAdapter): PaymentPayload | null { + // Check v2 header first (PAYMENT-SIGNATURE) + const header = adapter.getHeader("payment-signature") || adapter.getHeader("PAYMENT-SIGNATURE"); + + if (header) { + try { + return decodePaymentSignatureHeader(header); + } catch (error) { + console.warn("Failed to decode PAYMENT-SIGNATURE header:", error); + } + } + + return null; + } + + /** + * Check if request is from a web browser + * + * @param adapter - HTTP adapter + * @returns True if request appears to be from a browser + */ + private isWebBrowser(adapter: HTTPAdapter): boolean { + const accept = adapter.getAcceptHeader(); + const userAgent = adapter.getUserAgent(); + return accept.includes("text/html") && userAgent.includes("Mozilla"); + } + + /** + * Create HTTP response instructions from payment required + * + * @param paymentRequired - Payment requirements + * @param isWebBrowser - Whether request is from browser + * @param paywallConfig - Paywall configuration + * @param customHtml - Custom HTML template + * @returns Response instructions + */ + private createHTTPResponse( + paymentRequired: PaymentRequired, + isWebBrowser: boolean, + paywallConfig?: PaywallConfig, + customHtml?: string, + ): HTTPResponseInstructions { + if (isWebBrowser) { + const html = this.generatePaywallHTML(paymentRequired, paywallConfig, customHtml); + return { + status: 402, + headers: { "Content-Type": "text/html" }, + body: html, + isHtml: true, + }; + } + + const response = this.createHTTPPaymentRequiredResponse(paymentRequired); + return { + status: 402, + headers: { + "Content-Type": "application/json", + ...response.headers, + }, + }; + } + + /** + * Create HTTP payment required response (v1 puts in body, v2 puts in header) + * + * @param paymentRequired - Payment required object + * @returns Headers and body for the HTTP response + */ + private createHTTPPaymentRequiredResponse(paymentRequired: PaymentRequired): { + headers: Record; + } { + return { + headers: { + "PAYMENT-REQUIRED": encodePaymentRequiredHeader(paymentRequired), + }, + }; + } + + /** + * Create settlement response headers + * + * @param settleResponse - Settlement response + * @returns Headers to add to response + */ + private createSettlementHeaders(settleResponse: SettleResponse): Record { + const encoded = encodePaymentResponseHeader(settleResponse); + return { "PAYMENT-RESPONSE": encoded }; + } + + /** + * Parse route pattern into verb and regex + * + * @param pattern - Route pattern like "GET /api/*" or "/api/[id]" + * @returns Parsed pattern with verb and regex + */ + private parseRoutePattern(pattern: string): { verb: string; regex: RegExp } { + const [verb, path] = pattern.includes(" ") ? pattern.split(/\s+/) : ["*", pattern]; + + const regex = new RegExp( + `^${ + path + .replace(/[$()+.?^{|}]/g, "\\$&") // Escape regex special chars + .replace(/\*/g, ".*?") // Wildcards + .replace(/\[([^\]]+)\]/g, "[^/]+") // Parameters + .replace(/\//g, "\\/") // Escape slashes + }$`, + "i", + ); + + return { verb: verb.toUpperCase(), regex }; + } + + /** + * Normalize path for matching + * + * @param path - Raw path from request + * @returns Normalized path + */ + private normalizePath(path: string): string { + try { + const pathWithoutQuery = path.split(/[?#]/)[0]; + const decodedPath = decodeURIComponent(pathWithoutQuery); + return decodedPath + .replace(/\\/g, "/") + .replace(/\/+/g, "/") + .replace(/(.+?)\/+$/, "$1"); + } catch { + return path; + } + } + + /** + * Generate paywall HTML for browser requests + * + * @param paymentRequired - Payment required response + * @param paywallConfig - Optional paywall configuration + * @param customHtml - Optional custom HTML template + * @returns HTML string + */ + private generatePaywallHTML( + paymentRequired: PaymentRequired, + paywallConfig?: PaywallConfig, + customHtml?: string, + ): string { + if (customHtml) { + return customHtml; + } + + // Use custom paywall provider if set + if (this.paywallProvider) { + return this.paywallProvider.generateHtml(paymentRequired, paywallConfig); + } + + // Try to use @x402/paywall if available (optional dependency) + try { + // eslint-disable-next-line @typescript-eslint/no-require-imports + const paywall = require("@x402/paywall"); + const displayAmount = this.getDisplayAmount(paymentRequired); + const resource = paymentRequired.resource; + + return paywall.getPaywallHtml({ + amount: displayAmount, + paymentRequirements: paymentRequired.accepts, + currentUrl: resource?.url || paywallConfig?.currentUrl || "", + testnet: paywallConfig?.testnet ?? true, + cdpClientKey: paywallConfig?.cdpClientKey, + appName: paywallConfig?.appName, + appLogo: paywallConfig?.appLogo, + sessionTokenEndpoint: paywallConfig?.sessionTokenEndpoint, + }); + } catch { + // @x402/paywall not installed, fall back to basic HTML + } + + // Fallback: Basic HTML paywall + const resource = paymentRequired.resource; + const displayAmount = this.getDisplayAmount(paymentRequired); + + return ` + + + + Payment Required + + + + +
+ ${paywallConfig?.appLogo ? `${paywallConfig.appName || ` : ""} +

Payment Required

+ ${resource ? `

Resource: ${resource.description || resource.url}

` : ""} +

Amount: $${displayAmount.toFixed(2)} USDC

+
+ +

+ Note: Install @x402/paywall for full wallet connection and payment UI. +

+
+
+ + + `; + } + + /** + * Extract display amount from payment requirements. + * + * @param paymentRequired - The payment required object + * @returns The display amount in decimal format + */ + private getDisplayAmount(paymentRequired: PaymentRequired): number { + const accepts = paymentRequired.accepts; + if (accepts && accepts.length > 0) { + const firstReq = accepts[0]; + if ("amount" in firstReq) { + // V2 format + return parseFloat(firstReq.amount) / 1000000; // Assuming USDC with 6 decimals + } + } + return 0; + } +} diff --git a/typescript/packages/core/src/index.ts b/typescript/packages/core/src/index.ts new file mode 100644 index 000000000..3942c73e2 --- /dev/null +++ b/typescript/packages/core/src/index.ts @@ -0,0 +1 @@ +export const x402Version = 2; diff --git a/typescript/packages/core/src/server/index.ts b/typescript/packages/core/src/server/index.ts new file mode 100644 index 000000000..29d30d6ae --- /dev/null +++ b/typescript/packages/core/src/server/index.ts @@ -0,0 +1,18 @@ +export { x402ResourceService } from "./x402ResourceService"; +export type { ResourceConfig, ResourceInfo } from "./x402ResourceService"; + +export { HTTPFacilitatorClient } from "../http/httpFacilitatorClient"; +export type { FacilitatorClient, FacilitatorConfig } from "../http/httpFacilitatorClient"; + +export { x402HTTPResourceService } from "../http/x402HTTPResourceService"; +export type { + HTTPRequestContext, + HTTPResponseInstructions, + HTTPProcessResult, + PaywallConfig, + PaywallProvider, + RouteConfig, + CompiledRoute, + HTTPAdapter, + RoutesConfig, +} from "../http/x402HTTPResourceService"; diff --git a/typescript/packages/core/src/server/x402ResourceService.ts b/typescript/packages/core/src/server/x402ResourceService.ts new file mode 100644 index 000000000..e835a9767 --- /dev/null +++ b/typescript/packages/core/src/server/x402ResourceService.ts @@ -0,0 +1,500 @@ +import { SettleResponse, VerifyResponse, SupportedResponse } from "../types/facilitator"; +import { PaymentPayload, PaymentRequirements, PaymentRequired } from "../types/payments"; +import { SchemeNetworkService } from "../types/mechanisms"; +import { Price, Network } from "../types"; +import { deepEqual, findByNetworkAndScheme } from "../utils"; +import { FacilitatorClient, HTTPFacilitatorClient } from "../http/httpFacilitatorClient"; +import { x402Version } from ".."; + +/** + * Configuration for a protected resource + * Only contains payment-specific configuration, not resource metadata + */ +export interface ResourceConfig { + scheme: string; + payTo: string; // Payment recipient address + price: Price; + network: Network; + maxTimeoutSeconds?: number; +} + +/** + * Resource information for PaymentRequired response + */ +export interface ResourceInfo { + url: string; + description: string; + mimeType: string; +} + +/** + * Core x402 protocol server for resource protection + * Transport-agnostic implementation of the x402 payment protocol + */ +export class x402ResourceService { + private facilitatorClients: FacilitatorClient[]; + // Mapping: x402Version -> network -> scheme -> SupportedResponse | FacilitatorClient + private registeredServerSchemes: Map> = new Map(); + private supportedResponsesMap: Map>> = + new Map(); + private facilitatorClientsMap: Map>> = + new Map(); + + /** + * Creates a new x402ResourceService instance. + * + * @param facilitatorClients - Optional facilitator client(s) for payment processing + */ + constructor(facilitatorClients?: FacilitatorClient | FacilitatorClient[]) { + // Normalize facilitator clients to array + if (!facilitatorClients) { + // No clients provided, create a default HTTP client + this.facilitatorClients = [new HTTPFacilitatorClient()]; + } else if (Array.isArray(facilitatorClients)) { + // Array of clients provided + this.facilitatorClients = + facilitatorClients.length > 0 ? facilitatorClients : [new HTTPFacilitatorClient()]; + } else { + // Single client provided + this.facilitatorClients = [facilitatorClients]; + } + } + + /** + * Register a scheme/network server implementation. + * + * @param network - The network identifier + * @param server - The scheme/network server implementation + * @returns The x402ResourceService instance for chaining + */ + registerScheme(network: Network, server: SchemeNetworkService): x402ResourceService { + if (!this.registeredServerSchemes.has(network)) { + this.registeredServerSchemes.set(network, new Map()); + } + + const serverByScheme = this.registeredServerSchemes.get(network)!; + if (!serverByScheme.has(server.scheme)) { + serverByScheme.set(server.scheme, server); + } + + return this; + } + + /** + * Initialize by fetching supported kinds from all facilitators + * Creates mappings for supported responses and facilitator clients + * Earlier facilitators in the array get precedence + */ + async initialize(): Promise { + // Clear existing mappings + this.supportedResponsesMap.clear(); + this.facilitatorClientsMap.clear(); + + // Fetch supported kinds from all facilitator clients + // Process in order to give precedence to earlier facilitators + for (const facilitatorClient of this.facilitatorClients) { + try { + const supported = await facilitatorClient.getSupported(); + + // Process each supported kind + for (const kind of supported.kinds) { + // Get or create version map for supported responses + if (!this.supportedResponsesMap.has(kind.x402Version)) { + this.supportedResponsesMap.set(kind.x402Version, new Map()); + } + const responseVersionMap = this.supportedResponsesMap.get(kind.x402Version)!; + + // Get or create version map for facilitator clients + if (!this.facilitatorClientsMap.has(kind.x402Version)) { + this.facilitatorClientsMap.set(kind.x402Version, new Map()); + } + const clientVersionMap = this.facilitatorClientsMap.get(kind.x402Version)!; + + // Get or create network map for responses + if (!responseVersionMap.has(kind.network)) { + responseVersionMap.set(kind.network, new Map()); + } + const responseNetworkMap = responseVersionMap.get(kind.network)!; + + // Get or create network map for clients + if (!clientVersionMap.has(kind.network)) { + clientVersionMap.set(kind.network, new Map()); + } + const clientNetworkMap = clientVersionMap.get(kind.network)!; + + // Only store if not already present (gives precedence to earlier facilitators) + if (!responseNetworkMap.has(kind.scheme)) { + responseNetworkMap.set(kind.scheme, supported); + clientNetworkMap.set(kind.scheme, facilitatorClient); + } + } + } catch (error) { + // Log error but continue with other facilitators + console.warn(`Failed to fetch supported kinds from facilitator: ${error}`); + } + } + } + + /** + * Get supported kind for a specific version, network, and scheme + * + * @param x402Version - The x402 version + * @param network - The network identifier + * @param scheme - The payment scheme + * @returns The supported kind or undefined if not found + */ + getSupportedKind( + x402Version: number, + network: Network, + scheme: string, + ): SupportedResponse["kinds"][0] | undefined { + const versionMap = this.supportedResponsesMap.get(x402Version); + if (!versionMap) return undefined; + + const supportedResponse = findByNetworkAndScheme(versionMap, scheme, network); + if (!supportedResponse) return undefined; + + // Find the specific kind from the response + return supportedResponse.kinds.find( + kind => + kind.x402Version === x402Version && kind.network === network && kind.scheme === scheme, + ); + } + + /** + * Get facilitator extensions for a specific version, network, and scheme + * + * @param x402Version - The x402 version + * @param network - The network identifier + * @param scheme - The payment scheme + * @returns The facilitator extensions or empty array if not found + */ + getFacilitatorExtensions(x402Version: number, network: Network, scheme: string): string[] { + const versionMap = this.supportedResponsesMap.get(x402Version); + if (!versionMap) return []; + + const supportedResponse = findByNetworkAndScheme(versionMap, scheme, network); + return supportedResponse?.extensions || []; + } + + /** + * Build payment requirements for a protected resource + * + * @param resourceConfig - Configuration for the protected resource + * @returns Array of payment requirements + */ + async buildPaymentRequirements(resourceConfig: ResourceConfig): Promise { + const requirements: PaymentRequirements[] = []; + + // Find the matching server implementation + const scheme = resourceConfig.scheme; + const SchemeNetworkService = findByNetworkAndScheme( + this.registeredServerSchemes, + scheme, + resourceConfig.network, + ); + + if (!SchemeNetworkService) { + // Fallback to placeholder implementation if no server registered + // TODO: Remove this fallback once implementations are registered + console.warn( + `No server implementation registered for scheme: ${scheme}, network: ${resourceConfig.network}`, + ); + return requirements; + } + + // Find the matching supported kind from facilitator + const supportedKind = this.getSupportedKind( + x402Version, + resourceConfig.network, + SchemeNetworkService.scheme, + ); + + if (!supportedKind) { + throw new Error( + `Facilitator does not support ${SchemeNetworkService.scheme} on ${resourceConfig.network}. ` + + `Make sure to call initialize() to fetch supported kinds from facilitators.`, + ); + } + + // Get facilitator extensions for this combination + const facilitatorExtensions = this.getFacilitatorExtensions( + x402Version, + resourceConfig.network, + SchemeNetworkService.scheme, + ); + + // Parse the price using the scheme's price parser + const parsedPrice = SchemeNetworkService.parsePrice( + resourceConfig.price, + resourceConfig.network, + ); + + // Build base payment requirements from resource config + const baseRequirements: PaymentRequirements = { + scheme: SchemeNetworkService.scheme, + network: resourceConfig.network, + amount: parsedPrice.amount, + asset: parsedPrice.asset, + payTo: resourceConfig.payTo, + maxTimeoutSeconds: resourceConfig.maxTimeoutSeconds || 300, // Default 5 minutes + extra: { + ...parsedPrice.extra, + }, + }; + + // Delegate to the implementation for scheme-specific enhancements + const requirement = await SchemeNetworkService.enhancePaymentRequirements( + baseRequirements, + supportedKind, + facilitatorExtensions, + ); + + requirements.push(requirement); + return requirements; + } + + /** + * Create a payment required response + * + * @param requirements - Payment requirements + * @param resourceInfo - Resource information + * @param error - Error message + * @param extensions - Optional extensions + * @returns Payment required response object + */ + createPaymentRequiredResponse( + requirements: PaymentRequirements[], + resourceInfo: ResourceInfo, + error?: string, + extensions?: Record, + ): PaymentRequired { + // V2 response with resource at top level + const response: PaymentRequired = { + x402Version: 2, + error, + resource: resourceInfo, + accepts: requirements as PaymentRequirements[], + }; + + // Add extensions if provided + if (extensions && Object.keys(extensions).length > 0) { + response.extensions = extensions; + } + + return response; + } + + /** + * Verify a payment against requirements + * + * @param paymentPayload - The payment payload to verify + * @param requirements - The payment requirements + * @returns Verification response + */ + async verifyPayment( + paymentPayload: PaymentPayload, + requirements: PaymentRequirements, + ): Promise { + // Find the facilitator that supports this payment type + const facilitatorClient = this.getFacilitatorClient( + paymentPayload.x402Version, + requirements.network, + requirements.scheme, + ); + + if (!facilitatorClient) { + // Fallback: try all facilitators if no specific support found + let lastError: Error | undefined; + + for (const client of this.facilitatorClients) { + try { + return await client.verify(paymentPayload, requirements); + } catch (error) { + lastError = error as Error; + } + } + + throw ( + lastError || + new Error( + `No facilitator supports ${requirements.scheme} on ${requirements.network} for v${paymentPayload.x402Version}`, + ) + ); + } + + // Use the specific facilitator that supports this payment + try { + return await facilitatorClient.verify(paymentPayload, requirements); + } catch (error) { + throw new Error( + `Facilitator failed to verify ${requirements.scheme} on ${requirements.network}: ${error}`, + ); + } + } + + /** + * Settle a verified payment + * + * @param paymentPayload - The payment payload to settle + * @param requirements - The payment requirements + * @returns Settlement response + */ + async settlePayment( + paymentPayload: PaymentPayload, + requirements: PaymentRequirements, + ): Promise { + // Find the facilitator that supports this payment type + const facilitatorClient = this.getFacilitatorClient( + paymentPayload.x402Version, + requirements.network, + requirements.scheme, + ); + + if (!facilitatorClient) { + // Fallback: try all facilitators if no specific support found + let lastError: Error | undefined; + + for (const client of this.facilitatorClients) { + try { + return await client.settle(paymentPayload, requirements); + } catch (error) { + lastError = error as Error; + } + } + + throw ( + lastError || + new Error( + `No facilitator supports ${requirements.scheme} on ${requirements.network} for v${paymentPayload.x402Version}`, + ) + ); + } + + // Use the specific facilitator that supports this payment + try { + return await facilitatorClient.settle(paymentPayload, requirements); + } catch (error) { + throw new Error( + `Facilitator failed to settle ${requirements.scheme} on ${requirements.network}: ${error}`, + ); + } + } + + /** + * Find matching payment requirements for a payment + * + * @param availableRequirements - Array of available payment requirements + * @param paymentPayload - The payment payload + * @returns Matching payment requirements or undefined + */ + findMatchingRequirements( + availableRequirements: PaymentRequirements[], + paymentPayload: PaymentPayload, + ): PaymentRequirements | undefined { + switch (paymentPayload.x402Version) { + case 2: + // For v2, match by accepted requirements + return availableRequirements.find(paymentRequirements => + deepEqual(paymentRequirements, paymentPayload.accepted), + ); + case 1: + // For v1, match by scheme and network + return availableRequirements.find( + req => req.scheme === paymentPayload.scheme && req.network === paymentPayload.network, + ); + default: + throw new Error( + `Unsupported x402 version: ${(paymentPayload as PaymentPayload).x402Version}`, + ); + } + } + + /** + * Process a payment request + * + * @param paymentPayload - Optional payment payload if provided + * @param resourceConfig - Configuration for the protected resource + * @param resourceInfo - Information about the resource being accessed + * @param extensions - Optional extensions to include in the response + * @returns Processing result + */ + async processPaymentRequest( + paymentPayload: PaymentPayload | null, + resourceConfig: ResourceConfig, + resourceInfo: ResourceInfo, + extensions?: Record, + ): Promise<{ + success: boolean; + requiresPayment?: PaymentRequired; + verificationResult?: VerifyResponse; + settlementResult?: SettleResponse; + error?: string; + }> { + const requirements = await this.buildPaymentRequirements(resourceConfig); + + if (!paymentPayload) { + return { + success: false, + requiresPayment: this.createPaymentRequiredResponse( + requirements, + resourceInfo, + "Payment required", + extensions, + ), + }; + } + + // Find matching requirements + const matchingRequirements = this.findMatchingRequirements(requirements, paymentPayload); + if (!matchingRequirements) { + return { + success: false, + requiresPayment: this.createPaymentRequiredResponse( + requirements, + resourceInfo, + "No matching payment requirements found", + extensions, + ), + }; + } + + // Verify payment + const verificationResult = await this.verifyPayment(paymentPayload, matchingRequirements); + if (!verificationResult.isValid) { + return { + success: false, + error: verificationResult.invalidReason, + verificationResult, + }; + } + + // Payment verified, ready for settlement + return { + success: true, + verificationResult, + }; + } + + /** + * Get facilitator client for a specific version, network, and scheme + * + * @param x402Version - The x402 version + * @param network - The network identifier + * @param scheme - The payment scheme + * @returns The facilitator client or undefined if not found + */ + private getFacilitatorClient( + x402Version: number, + network: Network, + scheme: string, + ): FacilitatorClient | undefined { + const versionMap = this.facilitatorClientsMap.get(x402Version); + if (!versionMap) return undefined; + + // Use findByNetworkAndScheme for pattern matching + return findByNetworkAndScheme(versionMap, scheme, network); + } +} + +export default x402ResourceService; diff --git a/typescript/packages/core/src/types/facilitator.ts b/typescript/packages/core/src/types/facilitator.ts new file mode 100644 index 000000000..dcb18755f --- /dev/null +++ b/typescript/packages/core/src/types/facilitator.ts @@ -0,0 +1,36 @@ +import { PaymentPayload, PaymentRequirements } from "./payments"; +import { Network } from "./"; + +export type VerifyRequest = { + paymentPayload: PaymentPayload; + paymentRequirements: PaymentRequirements; +}; + +export type VerifyResponse = { + isValid: boolean; + invalidReason?: string; + payer?: string; +}; + +export type SettleRequest = { + paymentPayload: PaymentPayload; + paymentRequirements: PaymentRequirements; +}; + +export type SettleResponse = { + success: boolean; + errorReason?: string; + payer?: string; + transaction: string; + network: Network; +}; + +export type SupportedResponse = { + kinds: { + x402Version: number; + scheme: string; + network: Network; + extra?: Record; + }[]; + extensions: string[]; +}; diff --git a/typescript/packages/core/src/types/index.ts b/typescript/packages/core/src/types/index.ts new file mode 100644 index 000000000..747c92bdb --- /dev/null +++ b/typescript/packages/core/src/types/index.ts @@ -0,0 +1,31 @@ +export type { + VerifyRequest, + VerifyResponse, + SettleRequest, + SettleResponse, + SupportedResponse, +} from "./facilitator"; +export type { PaymentRequirements, PaymentPayload, PaymentRequired } from "./payments"; +export type { + SchemeNetworkClient, + SchemeNetworkFacilitator, + SchemeNetworkService, +} from "./mechanisms"; +export type { + PaymentRequirementsV1, + PaymentRequiredV1, + PaymentPayloadV1, + EVMNetworkV1, + SVMNetworkV1, +} from "./v1"; +export { EVM_NETWORKS, SVM_NETWORKS } from "./v1"; + +export type Network = `${string}:${string}`; + +export type Money = string | number; +export type AssetAmount = { + asset: string; + amount: string; + extra?: Record; +}; +export type Price = Money | AssetAmount; diff --git a/typescript/packages/core/src/types/mechanisms.ts b/typescript/packages/core/src/types/mechanisms.ts new file mode 100644 index 000000000..4c30bd183 --- /dev/null +++ b/typescript/packages/core/src/types/mechanisms.ts @@ -0,0 +1,63 @@ +import { SettleResponse, VerifyResponse } from "./facilitator"; +import { PaymentRequirements } from "./payments"; +import { PaymentPayload } from "./payments"; +import { Price, Network, AssetAmount } from "."; + +export interface SchemeNetworkClient { + readonly scheme: string; + + createPaymentPayload( + x402Version: number, + requirements: PaymentRequirements, + ): Promise; +} + +export interface SchemeNetworkFacilitator { + readonly scheme: string; + + verify(payload: PaymentPayload, requirements: PaymentRequirements): Promise; + settle(payload: PaymentPayload, requirements: PaymentRequirements): Promise; +} + +export interface SchemeNetworkService { + readonly scheme: string; + + /** + * Convert a user-friendly price to the scheme's specific amount and asset format + * + * @param price - User-friendly price (e.g., "$0.10", "0.10", { amount: "100000", asset: "USDC" }) + * @param network - The network identifier for context + * @returns The converted amount, asset identifier, and any extra metadata + * + * @example + * // For EVM networks with USDC: + * parsePrice("$0.10", "eip155:8453") => { amount: "100000", asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" } + * + * // For custom schemes: + * parsePrice("10 points", "custom:network") => { amount: "10", asset: "points" } + */ + parsePrice(price: Price, network: Network): AssetAmount; + + /** + * Build payment requirements for this scheme/network combination + * + * @param paymentRequirements - Base payment requirements with amount/asset already set + * @param supportedKind - The supported kind from facilitator's /supported endpoint + * @param supportedKind.x402Version - The x402 version + * @param supportedKind.scheme - The payment scheme + * @param supportedKind.network - The network identifier + * @param supportedKind.extra - Optional extra metadata + * @param facilitatorExtensions - Extensions supported by the facilitator + * @returns Enhanced payment requirements ready to be sent to clients + */ + enhancePaymentRequirements( + paymentRequirements: PaymentRequirements, + supportedKind: { + x402Version: number; + scheme: string; + network: Network; + extra?: Record; + }, + facilitatorExtensions: string[], + ): Promise; +} diff --git a/typescript/packages/core/src/types/payments.ts b/typescript/packages/core/src/types/payments.ts new file mode 100644 index 000000000..ff6fd7d68 --- /dev/null +++ b/typescript/packages/core/src/types/payments.ts @@ -0,0 +1,32 @@ +import { Network } from "./"; + +export type PaymentRequirements = { + scheme: string; + network: Network; + asset: string; + amount: string; + payTo: string; + maxTimeoutSeconds: number; + extra: Record; +}; + +export type PaymentRequired = { + x402Version: number; + error?: string; + resource: { + url: string; + description: string; + mimeType: string; + }; + accepts: PaymentRequirements[]; + extensions?: Record; +}; + +export type PaymentPayload = { + x402Version: number; + scheme: string; + network: Network; + payload: Record; + accepted: PaymentRequirements; + extensions?: Record; +}; diff --git a/typescript/packages/core/src/types/v1/index.ts b/typescript/packages/core/src/types/v1/index.ts new file mode 100644 index 000000000..00f197347 --- /dev/null +++ b/typescript/packages/core/src/types/v1/index.ts @@ -0,0 +1,79 @@ +import { Network } from "../"; + +// Payments +export type PaymentRequirementsV1 = { + scheme: string; + network: Network; + maxAmountRequired: string; + resource: string; + description: string; + mimeType: string; + outputSchema: Record; + payTo: string; + maxTimeoutSeconds: number; + asset: string; + extra: Record; +}; + +export type PaymentRequiredV1 = { + x402Version: 1; + error?: string; + accepts: PaymentRequirementsV1[]; +}; + +export type PaymentPayloadV1 = { + x402Version: 1; + scheme: string; + network: Network; + payload: Record; +}; + +// Facilitator Requests/Responses +export type VerifyRequestV1 = { + paymentPayload: PaymentPayloadV1; + paymentRequirements: PaymentRequirementsV1; +}; + +export type SettleRequestV1 = { + paymentPayload: PaymentPayloadV1; + paymentRequirements: PaymentRequirementsV1; +}; + +export type SettleResponseV1 = { + success: boolean; + errorReason?: string; + payer?: string; + transaction: string; + network: Network; +}; + +export type SupportedResponseV1 = { + kinds: { + x402Version: number; + scheme: string; + network: Network; + extra?: Record; + }[]; + extensions: string[]; +}; + +export const EVM_NETWORKS = [ + "abstract", + "abstract-testnet", + "base-sepolia", + "base", + "avalanche-fuji", + "avalanche", + "iotex", + "sei", + "sei-testnet", + "polygon", + "polygon-amoy", + "peaq", +]; + +export type EVMNetworkV1 = (typeof EVM_NETWORKS)[number]; + +export const SVM_NETWORKS = ["solana", "solana-devnet"]; + +export type SVMNetworkV1 = (typeof SVM_NETWORKS)[number]; diff --git a/typescript/packages/core/src/utils/index.ts b/typescript/packages/core/src/utils/index.ts new file mode 100644 index 000000000..dc69eab70 --- /dev/null +++ b/typescript/packages/core/src/utils/index.ts @@ -0,0 +1,110 @@ +import { Network } from "../types"; + +export const findSchemesByNetwork = ( + map: Map>, + network: Network, +): Map | undefined => { + // Direct match first + let implementationsByScheme = map.get(network); + + if (!implementationsByScheme) { + // Try pattern matching for registered network patterns + for (const [registeredNetworkPattern, implementations] of map.entries()) { + // Convert the registered network pattern to a regex + // e.g., "eip155:*" becomes /^eip155:.*$/ + const pattern = registeredNetworkPattern + .replace(/[.*+?^${}()|[\]\\]/g, "\\$&") // Escape special regex chars except * + .replace(/\\\*/g, ".*"); // Replace escaped * with .* + + const regex = new RegExp(`^${pattern}$`); + + if (regex.test(network)) { + implementationsByScheme = implementations; + break; + } + } + } + + return implementationsByScheme; +}; + +export const findByNetworkAndScheme = ( + map: Map>, + scheme: string, + network: Network, +): T | undefined => { + return findSchemesByNetwork(map, network)?.get(scheme); +}; + +export const Base64EncodedRegex = /^[A-Za-z0-9+/]*={0,2}$/; + +/** + * Encodes a string to base64 format + * + * @param data - The string to be encoded to base64 + * @returns The base64 encoded string + */ +export function safeBase64Encode(data: string): string { + if (typeof globalThis !== "undefined" && typeof globalThis.btoa === "function") { + return globalThis.btoa(data); + } + return Buffer.from(data).toString("base64"); +} + +/** + * Decodes a base64 string back to its original format + * + * @param data - The base64 encoded string to be decoded + * @returns The decoded string in UTF-8 format + */ +export function safeBase64Decode(data: string): string { + if (typeof globalThis !== "undefined" && typeof globalThis.atob === "function") { + return globalThis.atob(data); + } + return Buffer.from(data, "base64").toString("utf-8"); +} + +/** + * Deep equality comparison for payment requirements + * Uses a normalized JSON.stringify for consistent comparison + * + * @param obj1 - First object to compare + * @param obj2 - Second object to compare + * @returns True if objects are deeply equal + */ +export function deepEqual(obj1: unknown, obj2: unknown): boolean { + // Normalize and stringify both objects for comparison + // This handles nested objects, arrays, and different property orders + const normalize = (obj: unknown): string => { + // Handle primitives and null/undefined + if (obj === null || obj === undefined) return JSON.stringify(obj); + if (typeof obj !== "object") return JSON.stringify(obj); + + // Handle arrays + if (Array.isArray(obj)) { + return JSON.stringify( + obj.map(item => + typeof item === "object" && item !== null ? JSON.parse(normalize(item)) : item, + ), + ); + } + + // Handle objects - sort keys and recursively normalize values + const sorted: Record = {}; + Object.keys(obj as Record) + .sort() + .forEach(key => { + const value = (obj as Record)[key]; + sorted[key] = + typeof value === "object" && value !== null ? JSON.parse(normalize(value)) : value; + }); + return JSON.stringify(sorted); + }; + + try { + return normalize(obj1) === normalize(obj2); + } catch { + // Fallback to simple comparison if normalization fails + return JSON.stringify(obj1) === JSON.stringify(obj2); + } +} diff --git a/typescript/packages/core/test/integrations/core.test.ts b/typescript/packages/core/test/integrations/core.test.ts new file mode 100644 index 000000000..1717b5e35 --- /dev/null +++ b/typescript/packages/core/test/integrations/core.test.ts @@ -0,0 +1,187 @@ +import { beforeEach, describe, expect, it } from "vitest"; +import { x402Client, x402HTTPClient } from "../../src/client"; +import { x402Facilitator } from "../../src/facilitator"; +import { + HTTPAdapter, + HTTPResponseInstructions, + x402HTTPResourceService, + x402ResourceService, +} from "../../src/server"; +import { + buildCashPaymentRequirements, + CashFacilitatorClient, + CashSchemeNetworkClient, + CashSchemeNetworkFacilitator, + CashSchemeNetworkService, +} from "./mocks/cash"; +import { Network, PaymentPayload, PaymentRequirements } from "../../src/types"; + +describe("Core Integration Tests", () => { + describe("x402Client / x402ResourceService / x402Facilitator - Cash Flow", () => { + let client: x402Client; + let server: x402ResourceService; + + beforeEach(async () => { + client = new x402Client().registerScheme("x402:cash", new CashSchemeNetworkClient("John")); + + const facilitator = new x402Facilitator().registerScheme( + "x402:cash", + new CashSchemeNetworkFacilitator(), + ); + + const facilitatorClient = new CashFacilitatorClient(facilitator); + server = new x402ResourceService(facilitatorClient); + server.registerScheme("x402:cash", new CashSchemeNetworkService()); + await server.initialize(); // Initialize to fetch supported kinds + }); + + it("server should successfully verify and settle a cash payment from a client", async () => { + // Server - builds PaymentRequired response + const accepts = [buildCashPaymentRequirements("Company Co.", "USD", "1")]; + const resource = { + url: "https://company.co", + description: "Company Co. resource", + mimeType: "application/json", + }; + const paymentRequiredResponse = server.createPaymentRequiredResponse(accepts, resource); + + // Client - responds with PaymentPayload response + const selected = client.selectPaymentRequirements( + paymentRequiredResponse.x402Version, + accepts, + ); + const paymentPayload = await client.createPaymentPayload( + paymentRequiredResponse.x402Version, + selected, + ); + + // Server - maps payment payload to payment requirements + const accepted = server.findMatchingRequirements(accepts, paymentPayload); + expect(accepted).toBeDefined(); + + const verifyResponse = await server.verifyPayment(paymentPayload, accepted!); + expect(verifyResponse.isValid).toBe(true); + + // Server does work here + + const settleResponse = await server.settlePayment(paymentPayload, accepted!); + expect(settleResponse.success).toBe(true); + }); + }); + + describe("x402HTTPClient / x402HTTPResourceService / x402Facilitator - Cash Flow", () => { + let client: x402HTTPClient; + let service: x402HTTPResourceService; + + const routes = { + "/api/protected": { + scheme: "cash", + payTo: "merchant@example.com", + price: "$0.10", + network: "x402:cash" as Network, + description: "Access to protected API", + mimeType: "application/json", + }, + }; + + const mockAdapter: HTTPAdapter = { + getHeader: (name: string) => { + // Return payment header if requested + if (name === "x-payment") { + return "base64EncodedPaymentHere"; + } + return undefined; + }, + getMethod: () => "GET", + getPath: () => "/api/protected", + getUrl: () => "https://example.com/api/protected", + getAcceptHeader: () => "application/json", + getUserAgent: () => "TestClient/1.0", + }; + + beforeEach(async () => { + const facilitator = new x402Facilitator().registerScheme( + "x402:cash", + new CashSchemeNetworkFacilitator(), + ); + + const facilitatorClient = new CashFacilitatorClient(facilitator); + + client = new x402HTTPClient().registerScheme( + "x402:cash", + new CashSchemeNetworkClient("John"), + ) as x402HTTPClient; + + service = new x402HTTPResourceService(routes, facilitatorClient); + service.registerScheme("x402:cash", new CashSchemeNetworkService()); + await service.initialize(); // Initialize to fetch supported kinds + }); + + it("middleware should successfully verify and settle a cash payment from an http client", async () => { + // Middleware creates a PaymentRequired response + const context = { + adapter: mockAdapter, + path: "/api/protected", + method: "GET", + }; + // No payment made, get PaymentRequired response & header + const httpProcessResult = (await service.processHTTPRequest(context))!; + + expect(httpProcessResult.type).toBe("payment-error"); + + const initial402Response = ( + httpProcessResult as { type: "payment-error"; response: HTTPResponseInstructions } + ).response; + + expect(initial402Response).toBeDefined(); + expect(initial402Response.status).toBe(402); + expect(initial402Response.headers).toBeDefined(); + expect(initial402Response.headers["PAYMENT-REQUIRED"]).toBeDefined(); + expect(initial402Response.isHtml).toBeFalsy(); + expect(initial402Response.body).toBeUndefined(); + + // Client responds to PaymentRequired and submits a request with a PaymentPayload + const paymentRequired = client.getPaymentRequiredResponse( + initial402Response.headers, + initial402Response.body, + ); + const selected = client.selectPaymentRequirements( + paymentRequired.x402Version, + paymentRequired.accepts, + ); + const paymentPayload = await client.createPaymentPayload( + paymentRequired.x402Version, + selected, + ); + const requestHeaders = await client.encodePaymentSignatureHeader(paymentPayload); + + // Middleware handles PAYMENT-SIGNATURE request + context.adapter.getHeader = (name: string) => { + if (name === "PAYMENT-SIGNATURE") { + return requestHeaders["PAYMENT-SIGNATURE"]; + } + return undefined; + }; + const httpProcessResult2 = await service.processHTTPRequest(context); + + // No need to reason respond, can continue with request + expect(httpProcessResult2.type).toBe("payment-verified"); + const { + paymentPayload: verifiedPaymentPayload, + paymentRequirements: verifiedPaymentRequirements, + } = httpProcessResult2 as { + type: "payment-verified"; + paymentPayload: PaymentPayload; + paymentRequirements: PaymentRequirements; + }; + + const settlementHeaders = await service.processSettlement( + verifiedPaymentPayload, + verifiedPaymentRequirements, + 200, + ); + expect(settlementHeaders).toBeDefined(); + expect(settlementHeaders?.["PAYMENT-RESPONSE"]).toBeDefined(); + }); + }); +}); diff --git a/typescript/packages/core/test/integrations/mocks/cash/index.ts b/typescript/packages/core/test/integrations/mocks/cash/index.ts new file mode 100644 index 000000000..557c1f688 --- /dev/null +++ b/typescript/packages/core/test/integrations/mocks/cash/index.ts @@ -0,0 +1,290 @@ +import { x402Facilitator } from "../../../../src/facilitator"; +import { FacilitatorClient } from "../../../../src/server"; +import { + SettleResponse, + SupportedResponse, + VerifyResponse, +} from "../../../../src/types/facilitator"; +import { + SchemeNetworkClient, + SchemeNetworkFacilitator, + SchemeNetworkService, +} from "../../../../src/types/mechanisms"; +import { PaymentPayload, PaymentRequirements } from "../../../../src/types/payments"; +import { Price, AssetAmount, Network } from "../../../../src/types"; + +/** + * + */ +export class CashSchemeNetworkClient implements SchemeNetworkClient { + readonly scheme = "cash"; + + /** + * Creates a new CashClient instance. + * + * @param payer - The address of the payer + */ + constructor(private readonly payer: string) {} + + /** + * Creates a payment payload for the cash scheme. + * + * @param x402Version - The x402 protocol version + * @param requirements - The payment requirements + * @returns Promise resolving to the payment payload + */ + createPaymentPayload( + x402Version: number, + requirements: PaymentRequirements, + ): Promise { + return Promise.resolve({ + x402Version: 2, + scheme: requirements.scheme, + network: requirements.network, + payload: { + signature: `~${this.payer}`, + validUntil: (Date.now() + requirements.maxTimeoutSeconds).toString(), + name: this.payer, + }, + accepted: requirements, + }); + } +} + +/** + * + */ +export class CashSchemeNetworkFacilitator implements SchemeNetworkFacilitator { + readonly scheme = "cash"; + + /** + * Verifies a payment payload against requirements. + * + * @param payload - The payment payload to verify + * @param requirements - The payment requirements to verify against + * @returns Promise resolving to the verification response + */ + verify(payload: PaymentPayload, requirements: PaymentRequirements): Promise { + // Requirements parameter is not used in this implementation + void requirements; + if (payload.payload.signature !== `~${payload.payload.name}`) { + return Promise.resolve({ + isValid: false, + invalidReason: "invalid_signature", + payer: undefined, + }); + } + + if (payload.payload.validUntil < Date.now().toString()) { + return Promise.resolve({ + isValid: false, + invalidReason: "expired_signature", + payer: undefined, + }); + } + + return Promise.resolve({ + isValid: true, + invalidReason: undefined, + payer: payload.payload.signature, + }); + } + + /** + * Settles a payment based on the payload and requirements. + * + * @param payload - The payment payload to settle + * @param requirements - The payment requirements for settlement + * @returns Promise resolving to the settlement response + */ + async settle( + payload: PaymentPayload, + requirements: PaymentRequirements, + ): Promise { + const verifyResponse = await this.verify(payload, requirements); + if (!verifyResponse.isValid) { + return { + success: false, + errorReason: verifyResponse.invalidReason, + payer: verifyResponse.payer, + transaction: "", + network: requirements.network, + }; + } + + return { + success: true, + errorReason: undefined, + transaction: `${payload.payload.name} transferred ${requirements.amount} ${requirements.asset} to ${requirements.payTo}`, + network: requirements.network, + payer: payload.payload.signature, + }; + } +} + +/** + * Creates a payment receipt for the cash scheme. + * + * @param payTo - The recipient address + * @param asset - The asset being paid + * @param amount - The amount being paid + * @returns The payment receipt object + */ +export function buildCashPaymentRequirements( + payTo: string, + asset: string, + amount: string, +): PaymentRequirements { + return { + scheme: "cash", + network: "x402:cash", + asset: asset, + amount: amount, + payTo: payTo, + maxTimeoutSeconds: 1000, + extra: {}, + }; +} + +/** + * + */ +export class CashSchemeNetworkService implements SchemeNetworkService { + readonly scheme = "cash"; + + /** + * Parses a price into asset amount format. + * + * @param price - The price to parse + * @param network - The network identifier + * @returns The parsed asset amount + */ + parsePrice(price: Price, network: Network): AssetAmount { + // Network parameter is not used in this implementation + void network; + // Handle pre-parsed price object + if (typeof price === "object" && price !== null && "amount" in price) { + return { + amount: price.amount, + asset: price.asset || "USD", + extra: {}, + }; + } + + // Parse string prices like "$10" or "10 USD" + if (typeof price === "string") { + const cleanPrice = price + .replace(/^\$/, "") + .replace(/\s+USD$/i, "") + .trim(); + return { + amount: cleanPrice, + asset: "USD", + extra: {}, + }; + } + + // Handle number input + if (typeof price === "number") { + return { + amount: price.toString(), + asset: "USD", + extra: {}, + }; + } + + throw new Error(`Invalid price format: ${price}`); + } + + /** + * Enhances payment requirements with cash-specific details. + * + * @param paymentRequirements - Base payment requirements + * @param supportedKind - The supported kind from facilitator + * @param supportedKind.x402Version - The x402 version + * @param supportedKind.scheme - The payment scheme + * @param supportedKind.network - The network identifier + * @param supportedKind.extra - Optional extra metadata + * @param facilitatorExtensions - Extensions supported by facilitator + * @returns Promise resolving to enhanced payment requirements + */ + async enhancePaymentRequirements( + paymentRequirements: PaymentRequirements, + supportedKind: { + x402Version: number; + scheme: string; + network: Network; + extra?: Record; + }, + facilitatorExtensions: string[], + ): Promise { + // Cash scheme doesn't need any special enhancements + // Parameters are not used in this implementation + void supportedKind; + void facilitatorExtensions; + return paymentRequirements; + } +} + +/** + * + */ +export class CashFacilitatorClient implements FacilitatorClient { + readonly scheme = "cash"; + readonly network = "x402:cash"; + readonly x402Version = 2; + + /** + * Registers a facilitator for the cash scheme. + * + * @param facilitator - The cash facilitator to register + */ + constructor(private readonly facilitator: x402Facilitator) {} + + /** + * Verifies a payment payload against requirements. + * + * @param paymentPayload - The payment payload to verify + * @param paymentRequirements - The payment requirements to verify against + * @returns Promise resolving to the verification response + */ + verify( + paymentPayload: PaymentPayload, + paymentRequirements: PaymentRequirements, + ): Promise { + return this.facilitator.verify(paymentPayload, paymentRequirements); + } + + /** + * Settles a payment based on the payload and requirements. + * + * @param paymentPayload - The payment payload to settle + * @param paymentRequirements - The payment requirements for settlement + * @returns Promise resolving to the settlement response + */ + settle( + paymentPayload: PaymentPayload, + paymentRequirements: PaymentRequirements, + ): Promise { + return this.facilitator.settle(paymentPayload, paymentRequirements); + } + + /** + * Gets supported payment kinds and extensions. + * + * @returns Promise resolving to the supported response + */ + getSupported(): Promise { + return Promise.resolve({ + kinds: [ + { + x402Version: this.x402Version, + scheme: this.scheme, + network: this.network, + extra: {}, + }, + ], + extensions: [], + }); + } +} diff --git a/typescript/packages/x402/tsconfig.json b/typescript/packages/core/tsconfig.json similarity index 100% rename from typescript/packages/x402/tsconfig.json rename to typescript/packages/core/tsconfig.json diff --git a/typescript/packages/core/tsup.config.ts b/typescript/packages/core/tsup.config.ts new file mode 100644 index 000000000..3b9fb9fab --- /dev/null +++ b/typescript/packages/core/tsup.config.ts @@ -0,0 +1,34 @@ +import { defineConfig } from "tsup"; + +const baseConfig = { + entry: { + index: "src/index.ts", + "client/index": "src/client/index.ts", + "facilitator/index": "src/facilitator/index.ts", + "http/index": "src/http/index.ts", + "server/index": "src/server/index.ts", + "types/index": "src/types/index.ts", + "types/v1/index": "src/types/v1/index.ts", + "utils/index": "src/utils/index.ts", + }, + dts: { + resolve: true, + }, + sourcemap: true, + target: "es2020", +}; + +export default defineConfig([ + { + ...baseConfig, + format: "esm", + outDir: "dist/esm", + clean: true, + }, + { + ...baseConfig, + format: "cjs", + outDir: "dist/cjs", + clean: false, + }, +]); diff --git a/typescript/packages/coinbase-x402/vitest.config.ts b/typescript/packages/core/vitest.config.ts similarity index 100% rename from typescript/packages/coinbase-x402/vitest.config.ts rename to typescript/packages/core/vitest.config.ts diff --git a/typescript/packages/extensions/.prettierignore b/typescript/packages/extensions/.prettierignore new file mode 100644 index 000000000..9fd1bade5 --- /dev/null +++ b/typescript/packages/extensions/.prettierignore @@ -0,0 +1,7 @@ +docs/ +dist/ +node_modules/ +coverage/ +.github/ +**/**/*.json +*.md diff --git a/typescript/packages/extensions/.prettierrc b/typescript/packages/extensions/.prettierrc new file mode 100644 index 000000000..fae203e56 --- /dev/null +++ b/typescript/packages/extensions/.prettierrc @@ -0,0 +1,11 @@ +{ + "tabWidth": 2, + "useTabs": false, + "semi": true, + "singleQuote": false, + "trailingComma": "all", + "bracketSpacing": true, + "arrowParens": "avoid", + "printWidth": 100, + "proseWrap": "never" +} \ No newline at end of file diff --git a/typescript/packages/extensions/README.md b/typescript/packages/extensions/README.md new file mode 100644 index 000000000..071ae85c3 --- /dev/null +++ b/typescript/packages/extensions/README.md @@ -0,0 +1,45 @@ +# @x402/extensions + +x402 Payment Protocol Extensions + +## Installation + +```bash +npm install @x402/extensions +``` + +## Usage + +```typescript +// Specific extensions imported directly +import { declareDiscoveryExtension } from '@x402/extensions/bazaar'; + +// Many extensions imported together +import { declareDiscoveryExtension /* and any other extensions */ } from "@x402/extensions"; +``` + +## Development + +### Build + +```bash +npm run build +``` + +### Test + +```bash +npm run test +``` + +### Lint + +```bash +npm run lint +``` + +### Format + +```bash +npm run format +``` diff --git a/typescript/packages/extensions/eslint.config.js b/typescript/packages/extensions/eslint.config.js new file mode 100644 index 000000000..a276444eb --- /dev/null +++ b/typescript/packages/extensions/eslint.config.js @@ -0,0 +1,72 @@ +import js from "@eslint/js"; +import ts from "@typescript-eslint/eslint-plugin"; +import tsParser from "@typescript-eslint/parser"; +import prettier from "eslint-plugin-prettier"; +import jsdoc from "eslint-plugin-jsdoc"; +import importPlugin from "eslint-plugin-import"; + +export default [ + { + ignores: ["dist/**", "node_modules/**"], + }, + { + files: ["**/*.ts", "**/*.tsx"], + languageOptions: { + parser: tsParser, + sourceType: "module", + ecmaVersion: 2020, + globals: { + process: "readonly", + __dirname: "readonly", + module: "readonly", + require: "readonly", + Buffer: "readonly", + exports: "readonly", + setTimeout: "readonly", + clearTimeout: "readonly", + setInterval: "readonly", + clearInterval: "readonly", + }, + }, + plugins: { + "@typescript-eslint": ts, + prettier: prettier, + jsdoc: jsdoc, + import: importPlugin, + }, + rules: { + ...ts.configs.recommended.rules, + "import/first": "error", + "prettier/prettier": "error", + "@typescript-eslint/member-ordering": "error", + "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_$" }], + "jsdoc/tag-lines": ["error", "any", { startLines: 1 }], + "jsdoc/check-alignment": "error", + "jsdoc/no-undefined-types": "off", + "jsdoc/check-param-names": "error", + "jsdoc/check-tag-names": "error", + "jsdoc/check-types": "error", + "jsdoc/implements-on-classes": "error", + "jsdoc/require-description": "error", + "jsdoc/require-jsdoc": [ + "error", + { + require: { + FunctionDeclaration: true, + MethodDefinition: true, + ClassDeclaration: true, + ArrowFunctionExpression: false, + FunctionExpression: false, + }, + }, + ], + "jsdoc/require-param": "error", + "jsdoc/require-param-description": "error", + "jsdoc/require-param-type": "off", + "jsdoc/require-returns": "error", + "jsdoc/require-returns-description": "error", + "jsdoc/require-returns-type": "off", + "jsdoc/require-hyphen-before-param-description": ["error", "always"], + }, + }, +]; diff --git a/typescript/packages/extensions/package.json b/typescript/packages/extensions/package.json new file mode 100644 index 000000000..a6c4a64e5 --- /dev/null +++ b/typescript/packages/extensions/package.json @@ -0,0 +1,85 @@ +{ + "name": "@x402/extensions", + "version": "2.0.0", + "main": "./dist/cjs/index.js", + "module": "./dist/esm/index.js", + "types": "./dist/cjs/index.d.ts", + "scripts": { + "start": "tsx --env-file=.env index.ts", + "build": "tsup", + "test": "vitest run", + "test:watch": "vitest", + "watch": "tsc --watch", + "format": "prettier -c .prettierrc --write \"**/*.{ts,js,cjs,json,md}\"", + "format:check": "prettier -c .prettierrc --check \"**/*.{ts,js,cjs,json,md}\"", + "lint": "eslint . --ext .ts --fix", + "lint:check": "eslint . --ext .ts" + }, + "keywords": [ + "x402", + "payment", + "protocol", + "extensions" + ], + "license": "Apache-2.0", + "author": "Coinbase Inc.", + "repository": "https://github.com/coinbase/x402", + "description": "x402 Payment Protocol Extensions", + "devDependencies": { + "@eslint/js": "^9.24.0", + "@types/node": "^22.13.4", + "@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", + "tsup": "^8.4.0", + "tsx": "^4.19.2", + "typescript": "^5.7.3", + "vite": "^6.2.6", + "vite-tsconfig-paths": "^5.1.4", + "vitest": "^3.0.5" + }, + "dependencies": { + "@x402/core": "workspace:*", + "ajv": "^8.17.1", + "zod": "^3.24.2" + }, + "exports": { + ".": { + "import": { + "types": "./dist/esm/index.d.mts", + "default": "./dist/esm/index.mjs" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + } + }, + "./bazaar": { + "import": { + "types": "./dist/esm/bazaar/index.d.mts", + "default": "./dist/esm/bazaar/index.mjs" + }, + "require": { + "types": "./dist/cjs/bazaar/index.d.ts", + "default": "./dist/cjs/bazaar/index.js" + } + }, + "./sign-in-with-x": { + "import": { + "types": "./dist/esm/sign-in-with-x/index.d.mts", + "default": "./dist/esm/sign-in-with-x/index.mjs" + }, + "require": { + "types": "./dist/cjs/sign-in-with-x/index.d.ts", + "default": "./dist/cjs/sign-in-with-x/index.js" + } + } + }, + "files": [ + "dist" + ] +} \ No newline at end of file diff --git a/typescript/packages/extensions/src/bazaar/facilitator.ts b/typescript/packages/extensions/src/bazaar/facilitator.ts new file mode 100644 index 000000000..2da8275f4 --- /dev/null +++ b/typescript/packages/extensions/src/bazaar/facilitator.ts @@ -0,0 +1,217 @@ +/** + * Facilitator functions for validating and extracting Bazaar discovery extensions + * + * These functions help facilitators validate extension data against schemas + * and extract the discovery information for cataloging in the Bazaar. + * + * Supports both v2 (extensions in PaymentRequired) and v1 (outputSchema in PaymentRequirements). + */ + +import Ajv from "ajv/dist/2020"; +import type { PaymentPayload, PaymentRequirements, PaymentRequirementsV1 } from "@x402/core/types"; +import type { DiscoveryExtension, DiscoveryInfo } from "./types"; +import { BAZAAR } from "./types"; +import { extractDiscoveryInfoV1 } from "./v1/facilitator"; + +/** + * Validation result for discovery extensions + */ +export interface ValidationResult { + valid: boolean; + errors?: string[]; +} + +/** + * Validates a discovery extension's info against its schema + * + * @param extension - The discovery extension containing info and schema + * @returns Validation result indicating if the info matches the schema + * + * @example + * ```typescript + * const extension = declareDiscoveryExtension(...); + * const result = validateDiscoveryExtension(extension); + * + * if (result.valid) { + * console.log("Extension is valid"); + * } else { + * console.error("Validation errors:", result.errors); + * } + * ``` + */ +export function validateDiscoveryExtension( + extension: DiscoveryExtension +): ValidationResult { + try { + const ajv = new Ajv({ strict: false, allErrors: true }); + const validate = ajv.compile(extension.schema); + + // The schema describes the structure of info directly + // Schema has properties: { input: {...}, output: {...} } + // So we validate extension.info which has { input: {...}, output: {...} } + const valid = validate(extension.info); + + if (valid) { + return { valid: true }; + } + + const errors = validate.errors?.map((err) => { + const path = err.instancePath || "(root)"; + return `${path}: ${err.message}`; + }) || ["Unknown validation error"]; + + return { valid: false, errors }; + } catch (error) { + return { + valid: false, + errors: [`Schema validation failed: ${error instanceof Error ? error.message : String(error)}`], + }; + } +} + +/** + * Extracts the discovery info from payment payload and requirements + * + * This function handles both v2 (extensions) and v1 (outputSchema) formats. + * + * For v2: Discovery info is in PaymentPayload.extensions (client copied it from PaymentRequired) + * For v1: Discovery info is in PaymentRequirements.outputSchema + * + * V1 data is automatically transformed to v2 DiscoveryInfo format, making smart + * assumptions about field names (queryParams/query/params for GET, bodyFields/body/data for POST, etc.) + * + * @param paymentPayload - The payment payload containing extensions (v2) and version info + * @param paymentRequirements - The payment requirements (contains outputSchema for v1) + * @param validate - Whether to validate v2 extensions before extracting (default: true) + * @returns The discovery info in v2 format if present, or null if not discoverable + * + * @example + * ```typescript + * // V2 - extensions are in PaymentPayload + * const info = extractDiscoveryInfo(paymentPayload, paymentRequirements); + * + * // V1 - discovery info is in PaymentRequirements.outputSchema + * const info = extractDiscoveryInfo(paymentPayloadV1, paymentRequirementsV1); + * + * if (info) { + * // Both v1 and v2 return the same DiscoveryInfo structure + * console.log("Method:", info.input.method); + * } + * ``` + */ +export function extractDiscoveryInfo( + paymentPayload: PaymentPayload, + paymentRequirements: PaymentRequirements | PaymentRequirementsV1, + validate: boolean = true +): DiscoveryInfo | null { + // Try v2 first - extensions are in PaymentPayload (client copied from PaymentRequired) + if (paymentPayload.x402Version === 2 && paymentPayload.extensions) { + const bazaarExtension = paymentPayload.extensions[BAZAAR]; + + if (bazaarExtension && typeof bazaarExtension === "object") { + try { + const extension = bazaarExtension as DiscoveryExtension; + + if (validate) { + const result = validateDiscoveryExtension(extension); + if (!result.valid) { + // V2 validation failed, fall through to try v1 + console.warn( + `V2 discovery extension validation failed: ${result.errors?.join(", ")}` + ); + } else { + return extension.info; + } + } else { + return extension.info; + } + } catch (error) { + // V2 extraction failed, fall through to try v1 + console.warn(`V2 discovery extension extraction failed: ${error}`); + } + } + } + + // Try v1 format - discovery info is in PaymentRequirements.outputSchema + if (paymentPayload.x402Version === 1 || paymentPayload.x402Version === 2) { + // Cast to v1 format and try to extract + const requirementsV1 = paymentRequirements as PaymentRequirementsV1; + const infoV1 = extractDiscoveryInfoV1(requirementsV1); + + if (infoV1) { + return infoV1; + } + } + + // No discovery info found + return null; +} + +/** + * Extracts discovery info from a v2 extension directly + * + * This is a lower-level function for when you already have the extension object. + * For general use, prefer the main extractDiscoveryInfo function. + * + * @param extension - The discovery extension to extract info from + * @param validate - Whether to validate before extracting (default: true) + * @returns The discovery info if valid + * @throws Error if validation fails and validate is true + */ +export function extractDiscoveryInfoFromExtension( + extension: DiscoveryExtension, + validate: boolean = true +): DiscoveryInfo { + if (validate) { + const result = validateDiscoveryExtension(extension); + if (!result.valid) { + throw new Error( + `Invalid discovery extension: ${result.errors?.join(", ") || "Unknown error"}` + ); + } + } + + return extension.info; +} + +/** + * Validates and extracts discovery info in one step + * + * This is a convenience function that combines validation and extraction, + * returning both the validation result and the info if valid. + * + * @param extension - The discovery extension to validate and extract + * @returns Object containing validation result and info (if valid) + * + * @example + * ```typescript + * const extension = declareDiscoveryExtension(...); + * const { valid, info, errors } = validateAndExtract(extension); + * + * if (valid && info) { + * // Store info in Bazaar catalog + * } else { + * console.error("Validation errors:", errors); + * } + * ``` + */ +export function validateAndExtract(extension: DiscoveryExtension): { + valid: boolean; + info?: DiscoveryInfo; + errors?: string[]; +} { + const result = validateDiscoveryExtension(extension); + + if (result.valid) { + return { + valid: true, + info: extension.info, + }; + } + + return { + valid: false, + errors: result.errors, + }; +} + diff --git a/typescript/packages/extensions/src/bazaar/index.ts b/typescript/packages/extensions/src/bazaar/index.ts new file mode 100644 index 000000000..cd6304f87 --- /dev/null +++ b/typescript/packages/extensions/src/bazaar/index.ts @@ -0,0 +1,105 @@ +/** + * Bazaar Discovery Extension for x402 v2 and v1 + * + * Enables facilitators to automatically catalog and index x402-enabled resources + * by following the server's provided discovery instructions. + * + * ## V2 Usage + * + * The v2 extension follows a pattern where: + * - `info`: Contains the actual discovery data (the values) + * - `schema`: JSON Schema that validates the structure of `info` + * + * ### For Resource Servers (V2) + * + * ```typescript + * import { declareDiscoveryExtension, BAZAAR } from '@x402/extensions/bazaar'; + * + * // Declare a GET endpoint + * const extension = declareDiscoveryExtension( + * "GET", + * { query: "example" }, + * { + * properties: { + * query: { type: "string" } + * }, + * required: ["query"] + * } + * ); + * + * // Include in PaymentRequired response + * const paymentRequired = { + * x402Version: 2, + * resource: { ... }, + * accepts: [ ... ], + * extensions: { + * [BAZAAR]: extension + * } + * }; + * ``` + * + * ### For Facilitators (V2 and V1) + * + * ```typescript + * import { + * extractDiscoveryInfo, + * BAZAAR + * } from '@x402/extensions/bazaar'; + * + * // V2: Extensions are in PaymentPayload.extensions (client copied from PaymentRequired) + * // V1: Discovery info is in PaymentRequirements.outputSchema + * const info = extractDiscoveryInfo( + * paymentPayload, + * paymentRequirements + * ); + * + * if (info) { + * // Catalog info in Bazaar + * } + * ``` + * + * ## V1 Support + * + * V1 discovery information is stored in the `outputSchema` field of PaymentRequirements. + * The `extractDiscoveryInfo` function automatically handles v1 format as a fallback. + * + * ```typescript + * import { extractDiscoveryInfoV1 } from '@x402/extensions/bazaar/v1'; + * + * // Direct v1 extraction + * const infoV1 = extractDiscoveryInfoV1(paymentRequirementsV1); + * ``` + */ + +// Export types +export type { + DiscoveryInfo, + QueryDiscoveryInfo, + BodyDiscoveryInfo, + QueryDiscoveryExtension, + BodyDiscoveryExtension, + DiscoveryExtension, +} from "./types"; + +export { BAZAAR } from "./types"; + +// Export resource service functions (for servers) +export { + declareDiscoveryExtension, +} from "./resource-service"; + +// Export facilitator functions (for facilitators) +export { + validateDiscoveryExtension, + extractDiscoveryInfo, + extractDiscoveryInfoFromExtension, + validateAndExtract, + type ValidationResult, +} from "./facilitator"; + +// Export v1 functions (v1 data is transformed to v2 DiscoveryInfo format) +export { + extractDiscoveryInfoV1, + isDiscoverableV1, + extractResourceMetadataV1, +} from "./v1"; diff --git a/typescript/packages/extensions/src/bazaar/resource-service.ts b/typescript/packages/extensions/src/bazaar/resource-service.ts new file mode 100644 index 000000000..78149f49a --- /dev/null +++ b/typescript/packages/extensions/src/bazaar/resource-service.ts @@ -0,0 +1,220 @@ +/** + * Resource Service functions for creating Bazaar discovery extensions + * + * These functions help servers declare the shape of their endpoints + * for facilitator discovery and cataloging in the Bazaar. + */ + +import type { BodyMethods, QueryParamMethods } from "@x402/core/http"; +import { + type DiscoveryExtension, + type QueryDiscoveryExtension, + type BodyDiscoveryExtension, + type DeclareDiscoveryExtensionConfig, + type DeclareQueryDiscoveryExtensionConfig, + type DeclareBodyDiscoveryExtensionConfig, + isQueryExtensionConfig, + isBodyExtensionConfig, +} from "./types"; + +/** + * Internal helper to create a query discovery extension + */ +function createQueryDiscoveryExtension({ + method, + input = {}, + inputSchema = { properties: {} }, + output, +}: DeclareQueryDiscoveryExtensionConfig): QueryDiscoveryExtension { + return { + info: { + input: { + type: "http", + method, + ...(input && { queryParams: input }), + }, + ...(output?.example && { + output: { + type: "json", + example: output.example, + }, + }), + }, + schema: { + $schema: "https://json-schema.org/draft/2020-12/schema", + type: "object", + properties: { + input: { + type: "object", + properties: { + type: { + type: "string", + const: "http", + }, + method: { + type: "string", + enum: [method] as QueryParamMethods[], + }, + ...(inputSchema && { + queryParams: { + type: "object" as const, + ...inputSchema, + }, + }), + }, + required: ["type", "method"], + additionalProperties: false, + }, + ...(output?.example && { + output: { + type: "object" as const, + properties: { + type: { + type: "string" as const, + }, + example: { + type: "object" as const, + ...(output.schema || {}), + }, + }, + required: ["type"] as const, + }, + }), + }, + required: ["input"], + }, + }; +} + +/** + * Internal helper to create a body discovery extension + */ +function createBodyDiscoveryExtension({ + method, + input = {}, + inputSchema = { properties: {} }, + bodyType = "json", + output, +}: DeclareBodyDiscoveryExtensionConfig): BodyDiscoveryExtension { + + return { + info: { + input: { + type: "http", + method, + bodyType, + body: input, + }, + ...(output?.example && { + output: { + type: "json", + example: output.example, + }, + }), + }, + schema: { + $schema: "https://json-schema.org/draft/2020-12/schema", + type: "object", + properties: { + input: { + type: "object", + properties: { + type: { + type: "string", + const: "http", + }, + method: { + type: "string", + enum: [method] as BodyMethods[], + }, + bodyType: { + type: "string", + enum: ["json", "form-data", "text"], + }, + body: inputSchema, + }, + required: ["type", "method", "bodyType", "body"], + additionalProperties: false, + }, + ...(output?.example && { + output: { + type: "object" as const, + properties: { + type: { + type: "string" as const, + }, + example: { + type: "object" as const, + ...(output?.schema || {}), + }, + }, + required: ["type"] as const, + }, + }), + }, + required: ["input"], + }, + }; +} + +/** + * Create a discovery extension for any HTTP method + * + * This function helps servers declare how their endpoint should be called, + * including the expected input parameters/body and output format. + * + * @param config - Configuration object for the discovery extension + * @returns A discovery extension object with both info and schema + * + * @example + * ```typescript + * // For a GET endpoint with no input + * const getExtension = declareDiscoveryExtension({ + * method: "GET", + * output: { + * example: { message: "Success", timestamp: "2024-01-01T00:00:00Z" } + * } + * }); + * + * // For a GET endpoint with query params + * const getWithParams = declareDiscoveryExtension({ + * method: "GET", + * input: { query: "example" }, + * inputSchema: { + * properties: { + * query: { type: "string" } + * }, + * required: ["query"] + * } + * }); + * + * // For a POST endpoint with JSON body + * const postExtension = declareDiscoveryExtension({ + * method: "POST", + * input: { name: "John", age: 30 }, + * inputSchema: { + * properties: { + * name: { type: "string" }, + * age: { type: "number" } + * }, + * required: ["name"] + * }, + * bodyType: "json", + * output: { + * example: { success: true, id: "123" } + * } + * }); + * ``` + */ +export function declareDiscoveryExtension( + config: DeclareDiscoveryExtensionConfig +): DiscoveryExtension { + if (isQueryExtensionConfig(config)) { + return createQueryDiscoveryExtension(config); + } else if (isBodyExtensionConfig(config)) { + return createBodyDiscoveryExtension(config); + } else { + throw new Error(`Unsupported HTTP method: ${config}`); + } +} + diff --git a/typescript/packages/extensions/src/bazaar/types.ts b/typescript/packages/extensions/src/bazaar/types.ts new file mode 100644 index 000000000..8f3e4b851 --- /dev/null +++ b/typescript/packages/extensions/src/bazaar/types.ts @@ -0,0 +1,216 @@ +/** + * Type definitions for the Bazaar Discovery Extension + */ + +import type { BodyMethods, QueryParamMethods } from "@x402/core/http"; + +/** + * Extension identifier constant for the Bazaar discovery extension + */ +export const BAZAAR = "bazaar"; + +/** + * Discovery info for query parameter methods (GET, HEAD, DELETE) + */ +export interface QueryDiscoveryInfo { + input: { + type: "http"; + method: QueryParamMethods; + queryParams?: Record; + headers?: Record; + }; + output?: { + type?: string; + format?: string; + example?: any; + }; +} + +/** + * Discovery info for body methods (POST, PUT, PATCH) + */ +export interface BodyDiscoveryInfo { + input: { + type: "http"; + method: BodyMethods; + bodyType: "json" | "form-data" | "text"; + body: any; + queryParams?: Record; + headers?: Record; + }; + output?: { + type?: string; + format?: string; + example?: any; + }; +} + +/** + * Combined discovery info type + */ +export type DiscoveryInfo = QueryDiscoveryInfo | BodyDiscoveryInfo; + +/** + * Discovery extension for query parameter methods (GET, HEAD, DELETE) + */ +export interface QueryDiscoveryExtension { + info: QueryDiscoveryInfo; + + schema: { + $schema: "https://json-schema.org/draft/2020-12/schema"; + type: "object"; + properties: { + input: { + type: "object"; + properties: { + type: { + type: "string"; + const: "http"; + }; + method: { + type: "string"; + enum: QueryParamMethods[]; + }; + queryParams?: { + type: "object"; + properties?: Record; + required?: string[]; + additionalProperties?: boolean; + }; + headers?: { + type: "object"; + additionalProperties: { + type: "string"; + }; + }; + }; + required: ["type", "method"]; + additionalProperties?: boolean; + }; + output?: { + type: "object"; + properties?: Record; + additionalProperties?: boolean; + }; + }; + required: ["input"]; + }; +} + +/** + * Discovery extension for body methods (POST, PUT, PATCH) + */ +export interface BodyDiscoveryExtension { + info: BodyDiscoveryInfo; + + schema: { + $schema: "https://json-schema.org/draft/2020-12/schema"; + type: "object"; + properties: { + input: { + type: "object"; + properties: { + type: { + type: "string"; + const: "http"; + }; + method: { + type: "string"; + enum: BodyMethods[]; + }; + bodyType: { + type: "string"; + enum: ["json", "form-data", "text"]; + }; + body: Record; + queryParams?: { + type: "object"; + properties?: Record; + required?: string[]; + additionalProperties?: boolean; + }; + headers?: { + type: "object"; + additionalProperties: { + type: "string"; + }; + }; + }; + required: ["type", "method", "bodyType", "body"]; + additionalProperties?: boolean; + }; + output?: { + type: "object"; + properties?: Record; + additionalProperties?: boolean; + }; + }; + required: ["input"]; + }; +} + +/** + * Combined discovery extension type + */ +export type DiscoveryExtension = QueryDiscoveryExtension | BodyDiscoveryExtension; + + + +/** + * Configuration for declaring a discovery extension + */ +export interface DeclareQueryDiscoveryExtensionConfig { + /** HTTP method (GET, POST, PUT, PATCH, DELETE, HEAD) */ + method: QueryParamMethods; + + /** Example input data (query params for GET/HEAD/DELETE, body for POST/PUT/PATCH) */ + input?: any; + + /** JSON Schema for the input */ + inputSchema?: Record; + + /** Output configuration */ + output?: { + /** Example output data */ + example?: any; + /** JSON Schema for the output example */ + schema?: Record; + }; +} + +/** + * Configuration for declaring a discovery extension + */ +export interface DeclareBodyDiscoveryExtensionConfig { + /** HTTP method (GET, POST, PUT, PATCH, DELETE, HEAD) */ + method: BodyMethods; + + /** Example input data (query params for GET/HEAD/DELETE, body for POST/PUT/PATCH) */ + input?: any; + + /** JSON Schema for the input */ + inputSchema?: Record; + + /** Body type for POST/PUT/PATCH methods */ + bodyType?: "json" | "form-data" | "text"; + + /** Output configuration */ + output?: { + /** Example output data */ + example?: any; + /** JSON Schema for the output example */ + schema?: Record; + }; +} + +export type DeclareDiscoveryExtensionConfig = DeclareQueryDiscoveryExtensionConfig | DeclareBodyDiscoveryExtensionConfig; + + +// make it a typeguard +export const isQueryExtensionConfig = (config: DeclareDiscoveryExtensionConfig): config is DeclareQueryDiscoveryExtensionConfig => { + return ["GET", "HEAD", "DELETE"].includes(config.method); +} + +export const isBodyExtensionConfig = (config: DeclareDiscoveryExtensionConfig): config is DeclareBodyDiscoveryExtensionConfig => { + return ["POST", "PUT", "PATCH"].includes(config.method); +} \ No newline at end of file diff --git a/typescript/packages/extensions/src/bazaar/v1/facilitator.ts b/typescript/packages/extensions/src/bazaar/v1/facilitator.ts new file mode 100644 index 000000000..84665dbc4 --- /dev/null +++ b/typescript/packages/extensions/src/bazaar/v1/facilitator.ts @@ -0,0 +1,273 @@ +/** + * V1 Facilitator functions for extracting Bazaar discovery information + * + * In v1, discovery information is stored in the `outputSchema` field + * of PaymentRequirements, which has a different structure than v2. + * + * This module transforms v1 data into v2 DiscoveryInfo format. + */ + +import type { PaymentRequirementsV1 } from "@x402/core/types"; +import type { BodyMethods, QueryParamMethods } from "@x402/core/http"; +import type { DiscoveryInfo, QueryDiscoveryInfo, BodyDiscoveryInfo } from "../types"; + +/** + * Type guard to check if an object has the v1 outputSchema structure + */ +function hasV1OutputSchema(obj: any): obj is { input: any; output?: any } { + return ( + obj !== null && + typeof obj === "object" && + "input" in obj && + typeof obj.input === "object" && + "type" in obj.input && + obj.input.type === "http" && + "method" in obj.input + ); +} + +/** + * Checks if a method is a query parameter method + */ +function isQueryMethod(method: string): method is QueryParamMethods { + const upperMethod = method.toUpperCase(); + return upperMethod === "GET" || upperMethod === "HEAD" || upperMethod === "DELETE"; +} + +/** + * Checks if a method is a body method + */ +function isBodyMethod(method: string): method is BodyMethods { + const upperMethod = method.toUpperCase(); + return upperMethod === "POST" || upperMethod === "PUT" || upperMethod === "PATCH"; +} + +/** + * Extracts query parameters from v1 input, making smart assumptions + * about common field names used in v1 + */ +function extractQueryParams(v1Input: any): Record | undefined { + // Check various common field names used in v1 (both camelCase and snake_case) + if (v1Input.queryParams) { + return v1Input.queryParams; + } + if (v1Input.query_params) { + return v1Input.query_params; + } + if (v1Input.query) { + return v1Input.query; + } + if (v1Input.params) { + return v1Input.params; + } + return undefined; +} + +/** + * Extracts body information from v1 input, making smart assumptions + */ +function extractBodyInfo(v1Input: any): { body: any; bodyType: "json" | "form-data" | "text" } { + // Determine body type (check both camelCase and snake_case) + let bodyType: "json" | "form-data" | "text" = "json"; + const bodyTypeField = v1Input.bodyType || v1Input.body_type; + + if (bodyTypeField) { + const type = bodyTypeField.toLowerCase(); + if (type.includes("form") || type.includes("multipart")) { + bodyType = "form-data"; + } else if (type.includes("text") || type.includes("plain")) { + bodyType = "text"; + } else { + bodyType = "json"; + } + } + + // Extract body content from various possible fields + // Priority order based on observed patterns in real data + let body: any = {}; + + if (v1Input.bodyFields) { + body = v1Input.bodyFields; + } else if (v1Input.body_fields && v1Input.body_fields !== null) { + body = v1Input.body_fields; + } else if (v1Input.bodyParams) { + body = v1Input.bodyParams; + } else if (v1Input.body) { + body = v1Input.body; + } else if (v1Input.data) { + body = v1Input.data; + } else if (v1Input.properties) { + // Some endpoints have properties directly at the input level + body = v1Input.properties; + } + + return { body, bodyType }; +} + +/** + * Extracts discovery info from v1 PaymentRequirements and transforms to v2 format + * + * In v1, the discovery information is stored in the `outputSchema` field, + * which contains both input (endpoint shape) and output (response schema) information. + * + * This function makes smart assumptions to normalize v1 data into v2 DiscoveryInfo format: + * - For GET/HEAD/DELETE: Looks for queryParams, query, or params fields + * - For POST/PUT/PATCH: Looks for bodyFields, body, or data fields and normalizes bodyType + * - Extracts optional headers if present + * + * @param paymentRequirements - V1 payment requirements + * @returns Discovery info in v2 format if present and valid, or null if not discoverable + * + * @example + * ```typescript + * const requirements: PaymentRequirementsV1 = { + * scheme: "exact", + * network: "eip155:8453", + * maxAmountRequired: "100000", + * resource: "https://api.example.com/data", + * description: "Get data", + * mimeType: "application/json", + * outputSchema: { + * input: { + * type: "http", + * method: "GET", + * discoverable: true, + * queryParams: { query: "string" } + * }, + * output: { type: "object" } + * }, + * payTo: "0x...", + * maxTimeoutSeconds: 300, + * asset: "0x...", + * extra: {} + * }; + * + * const info = extractDiscoveryInfoV1(requirements); + * if (info) { + * console.log("Endpoint method:", info.input.method); + * } + * ``` + */ +export function extractDiscoveryInfoV1( + paymentRequirements: PaymentRequirementsV1 +): DiscoveryInfo | null { + const { outputSchema } = paymentRequirements; + + // Check if outputSchema exists and has the expected structure + if (!outputSchema || !hasV1OutputSchema(outputSchema)) { + return null; + } + + const v1Input = outputSchema.input; + + // Check if the endpoint is marked as discoverable + // Default to true if not specified (for backwards compatibility) + const isDiscoverable = v1Input.discoverable ?? true; + + if (!isDiscoverable) { + return null; + } + + const method = v1Input.method.toUpperCase(); + + // Extract headers if present (check both camelCase and snake_case) + const headers = v1Input.headerFields || v1Input.header_fields || v1Input.headers; + + // Extract output example/schema if present + const output = outputSchema.output + ? { + type: "json" as const, + example: outputSchema.output, + } + : undefined; + + // Transform based on method type + if (isQueryMethod(method)) { + // Query parameter method (GET, HEAD, DELETE) + const queryParams = extractQueryParams(v1Input); + + const discoveryInfo: QueryDiscoveryInfo = { + input: { + type: "http", + method: method as QueryParamMethods, + ...(queryParams && { queryParams }), + ...(headers && { headers }), + }, + ...(output && { output }), + }; + + return discoveryInfo; + } else if (isBodyMethod(method)) { + // Body method (POST, PUT, PATCH) + const { body, bodyType } = extractBodyInfo(v1Input); + const queryParams = extractQueryParams(v1Input); // Some POST requests also have query params + + const discoveryInfo: BodyDiscoveryInfo = { + input: { + type: "http", + method: method as BodyMethods, + bodyType, + body, + ...(queryParams && { queryParams }), + ...(headers && { headers }), + }, + ...(output && { output }), + }; + + return discoveryInfo; + } + + // Unsupported method, return null + return null; +} + +/** + * Checks if v1 PaymentRequirements contains discoverable information + * + * @param paymentRequirements - V1 payment requirements + * @returns True if the requirements contain valid discovery info + * + * @example + * ```typescript + * if (isDiscoverableV1(requirements)) { + * const info = extractDiscoveryInfoV1(requirements); + * // Catalog info in Bazaar + * } + * ``` + */ +export function isDiscoverableV1( + paymentRequirements: PaymentRequirementsV1 +): boolean { + return extractDiscoveryInfoV1(paymentRequirements) !== null; +} + +/** + * Extracts resource metadata from v1 PaymentRequirements + * + * In v1, resource information is embedded directly in the payment requirements + * rather than in a separate resource object. + * + * @param paymentRequirements - V1 payment requirements + * @returns Resource metadata + * + * @example + * ```typescript + * const metadata = extractResourceMetadataV1(requirements); + * console.log("Resource URL:", metadata.url); + * console.log("Description:", metadata.description); + * ``` + */ +export function extractResourceMetadataV1( + paymentRequirements: PaymentRequirementsV1 +): { + url: string; + description: string; + mimeType: string; +} { + return { + url: paymentRequirements.resource, + description: paymentRequirements.description, + mimeType: paymentRequirements.mimeType, + }; +} + diff --git a/typescript/packages/extensions/src/bazaar/v1/index.ts b/typescript/packages/extensions/src/bazaar/v1/index.ts new file mode 100644 index 000000000..c01a62bcf --- /dev/null +++ b/typescript/packages/extensions/src/bazaar/v1/index.ts @@ -0,0 +1,13 @@ +/** + * V1 Bazaar Discovery Extension + * + * Provides functions for extracting discovery information from v1 PaymentRequirements + * and transforming it to v2 DiscoveryInfo format. + */ + +export { + extractDiscoveryInfoV1, + isDiscoverableV1, + extractResourceMetadataV1, +} from "./facilitator"; + diff --git a/typescript/packages/extensions/src/index.ts b/typescript/packages/extensions/src/index.ts new file mode 100644 index 000000000..9e5806656 --- /dev/null +++ b/typescript/packages/extensions/src/index.ts @@ -0,0 +1,2 @@ +export * from "./bazaar"; +export * from "./sign-in-with-x"; \ No newline at end of file diff --git a/typescript/packages/extensions/src/sign-in-with-x/TODO.md b/typescript/packages/extensions/src/sign-in-with-x/TODO.md new file mode 100644 index 000000000..d7c902418 --- /dev/null +++ b/typescript/packages/extensions/src/sign-in-with-x/TODO.md @@ -0,0 +1,146 @@ +# Sign-In-With-X Extension TODO + +## Overview + +Implement the Sign-In-With-X (SIWx) extension for the x402 protocol, providing CAIP-122 standard wallet-based identity assertions. This extension allows clients to prove control of a wallet that may have previously paid for a resource, enabling servers to grant access without requiring repurchase. + +## Core Exports Required + +### Server-Side Exports + +```typescript +// Extension declaration helper for servers +export function declareSIWxExtension(options: { + resourceUri: string; // Full URI of the resource (domain derived from this) + statement?: string; + version?: string; // Defaults to "1" + network: `${string}:${string}`; // e.g., "eip155:8453" + expirationTime?: string; // Auto-set to +5 minutes if not provided + signatureScheme?: 'eip191' | 'eip712' | 'eip1271' | 'eip6492' | 'siws' | 'sep10'; +}): SIWxExtension; + +// Header parsing for servers +export function parseSIWxHeader(header: string): SIWxPayload; + +// Message validation +export function validateSIWxMessage( + message: SIWxPayload, + expectedResourceUri: string, // Validates domain is derived correctly from URI + options?: { + maxAge?: number; // Maximum age of issuedAt (default: 5 minutes) + checkNonce?: (nonce: string) => boolean; // Custom nonce validation + } +): { valid: boolean; error?: string }; + +// Signature verification +export function verifySIWxSignature( + message: SIWxPayload, + signature: string, + options?: { + provider?: any; // Web3 provider for on-chain verification + checkSmartWallet?: boolean; // Enable EIP-1271/6492 verification + } +): Promise<{ valid: boolean; address?: string; error?: string }>; +``` + +### Client-Side Exports + +```typescript +// Header encoding for clients +export function encodeSIWxHeader(payload: SIWxPayload): string; + +// Message construction helper +export function createSIWxMessage( + serverInfo: SIWxExtensionInfo, + address: string +): string; // Returns CAIP-122 formatted message string + +// Signature creation +export function signSIWxMessage( + message: string, + signer: any, // Wallet/signer interface + options?: { + signatureScheme?: 'eip191' | 'eip712' | 'eip1271' | 'eip6492'; + } +): Promise; + +// Complete flow helper +export function createSIWxPayload( + serverExtension: SIWxExtension, + signer: any +): Promise; +``` + +### Type Definitions + +```typescript +export interface SIWxExtensionInfo { + domain: string; // Auto-derived from resourceUri (without https://) + uri: string; // Same as resourceUri + statement?: string; + version: string; + chainId: string; // Derived from network (e.g., "eip155:8453") + nonce: string; // Auto-generated by SDK + issuedAt: string; // Auto-generated by SDK + expirationTime?: string; + notBefore?: string; + requestId?: string; + resources: string[]; // Auto-generated as [resourceUri] + signatureScheme?: string; +} + +export interface SIWxExtension { + info: SIWxExtensionInfo; + schema: object; // JSON Schema for validation +} + +export interface SIWxPayload { + domain: string; + address: string; + statement?: string; + uri: string; + version: string; + chainId: string; + nonce: string; + issuedAt: string; + expirationTime?: string; + notBefore?: string; + requestId?: string; + resources?: string[]; + signature: string; +} +``` + +## Implementation Requirements + +### Auto-Generated Fields + +The SDK will automatically generate the following fields from the provided options: +- **domain**: Extracted from `resourceUri` by removing the protocol (https://) +- **uri**: Same as the provided `resourceUri` +- **chainId**: Same as the provided `network` parameter +- **nonce**: Cryptographically secure random string +- **issuedAt**: Current timestamp in ISO 8601 format +- **resources**: Array containing the `resourceUri` + +### CAIP-122 Message Format + +Implement proper CAIP-122 message construction: +``` +{domain} wants you to sign in with your {chainId} account: +{address} + +{statement} + +URI: {uri} +Version: {version} +Chain ID: {chainId} +Nonce: {nonce} +Issued At: {issuedAt} +Expiration Time: {expirationTime} +Not Before: {notBefore} +Request ID: {requestId} +Resources: +- {resource1} +- {resource2} +``` diff --git a/typescript/packages/extensions/src/sign-in-with-x/index.ts b/typescript/packages/extensions/src/sign-in-with-x/index.ts new file mode 100644 index 000000000..129bd8c55 --- /dev/null +++ b/typescript/packages/extensions/src/sign-in-with-x/index.ts @@ -0,0 +1,10 @@ +/** + * @x402/sign-in-with-x - x402 Payment Protocol Sign-In-With-X Extension + * + * This module provides Sign-In-With-X authentication capabilities for the x402 payment protocol. + */ + +// Export Sign-In-With-X extension modules here +// The actual implementation logic will be added later + +export { }; diff --git a/typescript/packages/extensions/test/bazaar.test.ts b/typescript/packages/extensions/test/bazaar.test.ts new file mode 100644 index 000000000..416b32e71 --- /dev/null +++ b/typescript/packages/extensions/test/bazaar.test.ts @@ -0,0 +1,967 @@ +/** + * Tests for Bazaar Discovery Extension + */ + +import { describe, it, expect } from "vitest"; +import { + BAZAAR, + declareDiscoveryExtension, + validateDiscoveryExtension, + extractDiscoveryInfo, + extractDiscoveryInfoFromExtension, + extractDiscoveryInfoV1, + validateAndExtract, +} from "../src/bazaar/index"; +import type { BodyDiscoveryInfo, DiscoveryExtension } from "../src/bazaar/types"; + +describe("Bazaar Discovery Extension", () => { + describe("BAZAAR constant", () => { + it("should export the correct extension identifier", () => { + expect(BAZAAR).toBe("bazaar"); + }); + }); + + describe("declareDiscoveryExtension - GET method", () => { + it("should create a valid GET extension with query params", () => { + const extension = declareDiscoveryExtension({ + method: "GET", + input: { query: "test", limit: 10 }, + inputSchema: { + properties: { + query: { type: "string" }, + limit: { type: "number" }, + }, + required: ["query"], + }, + }); + + expect(extension).toHaveProperty("info"); + expect(extension).toHaveProperty("schema"); + expect(extension.info.input.method).toBe("GET"); + expect(extension.info.input.type).toBe("http"); + expect(extension.info.input.queryParams).toEqual({ query: "test", limit: 10 }); + }); + + it("should create a GET extension with output example", () => { + const outputExample = { results: [], total: 0 }; + const extension = declareDiscoveryExtension({ + method: "GET", + input: { query: "test" }, + inputSchema: { + properties: { + query: { type: "string" }, + }, + }, + output: { + example: outputExample, + }, + }); + + expect(extension.info.output?.example).toEqual(outputExample); + }); + }); + + describe("declareDiscoveryExtension - POST method", () => { + it("should create a valid POST extension with JSON body", () => { + const extension = declareDiscoveryExtension({ + method: "POST", + input: { name: "John", age: 30 }, + inputSchema: { + properties: { + name: { type: "string" }, + age: { type: "number" }, + }, + required: ["name"], + }, + bodyType: "json", + }); + + expect(extension.info.input.method).toBe("POST"); + expect(extension.info.input.type).toBe("http"); + expect((extension.info as BodyDiscoveryInfo).input.bodyType).toBe("json"); + expect((extension.info as BodyDiscoveryInfo).input.body).toEqual({ name: "John", age: 30 }); + }); + + it("should default to JSON body type if not specified", () => { + const extension = declareDiscoveryExtension({ + method: "POST", + input: { data: "test" }, + inputSchema: { + properties: { + data: { type: "string" }, + }, + }, + }); + + expect((extension.info as BodyDiscoveryInfo).input.bodyType).toBe("json"); + }); + + it("should support form-data body type", () => { + const extension = declareDiscoveryExtension({ + method: "POST", + input: { file: "upload.pdf" }, + inputSchema: { + properties: { + file: { type: "string" }, + }, + }, + bodyType: "form-data", + }); + + expect((extension.info as BodyDiscoveryInfo).input.bodyType).toBe("form-data"); + }); + }); + + describe("declareDiscoveryExtension - Other methods", () => { + it("should create a valid PUT extension", () => { + const extension = declareDiscoveryExtension({ + method: "PUT", + input: { id: "123", name: "Updated" }, + inputSchema: { + properties: { + id: { type: "string" }, + name: { type: "string" }, + }, + }, + }); + + expect(extension.info.input.method).toBe("PUT"); + }); + + it("should create a valid PATCH extension", () => { + const extension = declareDiscoveryExtension({ + method: "PATCH", + input: { status: "active" }, + inputSchema: { + properties: { + status: { type: "string" }, + }, + }, + }); + + expect(extension.info.input.method).toBe("PATCH"); + }); + + it("should create a valid DELETE extension", () => { + const extension = declareDiscoveryExtension({ + method: "DELETE", + input: { id: "123" }, + inputSchema: { + properties: { + id: { type: "string" }, + }, + }, + }); + + expect(extension.info.input.method).toBe("DELETE"); + }); + + it("should create a valid HEAD extension", () => { + const extension = declareDiscoveryExtension({ + method: "HEAD", + }); + + expect(extension.info.input.method).toBe("HEAD"); + }); + + it("should throw error for unsupported method", () => { + expect(() => { + declareDiscoveryExtension({ + method: "INVALID" as any, + }); + }).toThrow("Unsupported HTTP method: INVALID"); + }); + }); + + describe("validateDiscoveryExtension", () => { + it("should validate a correct GET extension", () => { + const extension = declareDiscoveryExtension({ + method: "GET", + input: { query: "test" }, + inputSchema: { + properties: { + query: { type: "string" }, + }, + }, + }); + + const result = validateDiscoveryExtension(extension); + expect(result.valid).toBe(true); + expect(result.errors).toBeUndefined(); + }); + + it("should validate a correct POST extension", () => { + const extension = declareDiscoveryExtension({ + method: "POST", + input: { name: "John" }, + inputSchema: { + properties: { + name: { type: "string" }, + }, + }, + }); + + const result = validateDiscoveryExtension(extension); + expect(result.valid).toBe(true); + }); + + it("should detect invalid extension structure", () => { + const invalidExtension = { + info: { + input: { + type: "http", + method: "GET", + }, + }, + schema: { + $schema: "https://json-schema.org/draft/2020-12/schema", + type: "object", + properties: { + input: { + type: "object", + properties: { + type: { type: "string", const: "invalid" }, // Should be "http" + method: { type: "string", enum: ["GET"] }, + }, + required: ["type", "method"], + }, + }, + required: ["input"], + }, + } as unknown as DiscoveryExtension; + + const result = validateDiscoveryExtension(invalidExtension); + expect(result.valid).toBe(false); + expect(result.errors).toBeDefined(); + expect(result.errors!.length).toBeGreaterThan(0); + }); + }); + + describe("extractDiscoveryInfoFromExtension", () => { + it("should extract info from a valid extension", () => { + const extension = declareDiscoveryExtension({ + method: "GET", + input: { query: "test" }, + inputSchema: { + properties: { + query: { type: "string" }, + }, + }, + }); + + const info = extractDiscoveryInfoFromExtension(extension); + expect(info).toEqual(extension.info); + expect(info.input.method).toBe("GET"); + expect(info.input.type).toBe("http"); + }); + + it("should extract info without validation when validate=false", () => { + const extension = declareDiscoveryExtension({ + method: "POST", + input: { name: "John" }, + inputSchema: { + properties: { + name: { type: "string" }, + }, + }, + }); + + const info = extractDiscoveryInfoFromExtension(extension, false); + expect(info).toEqual(extension.info); + }); + + it("should throw error for invalid extension when validating", () => { + const invalidExtension = { + info: { + input: { + type: "http", + method: "GET", + }, + }, + schema: { + $schema: "https://json-schema.org/draft/2020-12/schema", + type: "object", + properties: { + input: { + type: "object", + properties: { + type: { type: "string", const: "invalid" }, + method: { type: "string", enum: ["GET"] }, + }, + required: ["type", "method"], + }, + }, + required: ["input"], + }, + } as unknown as DiscoveryExtension; + + expect(() => { + extractDiscoveryInfoFromExtension(invalidExtension); + }).toThrow("Invalid discovery extension"); + }); + }); + + describe("extractDiscoveryInfo (full flow)", () => { + it("should extract info from v2 PaymentPayload with extensions", () => { + const extension = declareDiscoveryExtension({ + method: "POST", + input: { userId: "123" }, + inputSchema: { + properties: { + userId: { type: "string" }, + }, + }, + }); + + const paymentPayload = { + x402Version: 2, + scheme: "exact", + network: "eip155:8453" as any, + payload: {}, + accepted: {} as any, + extensions: { + [BAZAAR]: extension, + }, + }; + + const info = extractDiscoveryInfo(paymentPayload, {} as any); + + expect(info).not.toBeNull(); + expect(info!.input.method).toBe("POST"); + expect(info!.input.type).toBe("http"); + }); + + it("should extract info from v1 PaymentRequirements", () => { + const v1Requirements = { + scheme: "exact", + network: "eip155:8453" as any, + maxAmountRequired: "10000", + resource: "https://api.example.com/data", + description: "Get data", + mimeType: "application/json", + outputSchema: { + input: { + type: "http", + method: "GET", + discoverable: true, + queryParams: { q: "test" }, + }, + }, + payTo: "0x...", + maxTimeoutSeconds: 300, + asset: "0x...", + extra: {}, + }; + + const v1Payload = { + x402Version: 1, + scheme: "exact", + network: "eip155:8453" as any, + payload: {}, + }; + + const info = extractDiscoveryInfo(v1Payload as any, v1Requirements as any); + + expect(info).not.toBeNull(); + expect(info!.input.method).toBe("GET"); + expect(info!.input.type).toBe("http"); + }); + + it("should return null when no discovery info is present", () => { + const paymentPayload = { + x402Version: 2, + scheme: "exact", + network: "eip155:8453" as any, + payload: {}, + accepted: {} as any, + }; + + const info = extractDiscoveryInfo(paymentPayload, {} as any); + + expect(info).toBeNull(); + }); + }); + + describe("validateAndExtract", () => { + it("should return valid result with info for correct extension", () => { + const extension = declareDiscoveryExtension({ + method: "GET", + input: { query: "test" }, + inputSchema: { + properties: { + query: { type: "string" }, + }, + }, + }); + + const result = validateAndExtract(extension); + expect(result.valid).toBe(true); + expect(result.info).toEqual(extension.info); + expect(result.errors).toBeUndefined(); + }); + + it("should return invalid result with errors for incorrect extension", () => { + const invalidExtension = { + info: { + input: { + type: "http", + method: "GET", + }, + }, + schema: { + $schema: "https://json-schema.org/draft/2020-12/schema", + type: "object", + properties: { + input: { + type: "object", + properties: { + type: { type: "string", const: "invalid" }, + method: { type: "string", enum: ["GET"] }, + }, + required: ["type", "method"], + }, + }, + required: ["input"], + }, + } as unknown as DiscoveryExtension; + + const result = validateAndExtract(invalidExtension); + expect(result.valid).toBe(false); + expect(result.info).toBeUndefined(); + expect(result.errors).toBeDefined(); + expect(result.errors!.length).toBeGreaterThan(0); + }); + }); + + describe("V1 Transformation", () => { + it("should extract discovery info from v1 GET with no params", () => { + const v1Requirements = { + scheme: "exact", + network: "eip155:8453" as any, + maxAmountRequired: "100000", + resource: "https://api.example.com/data", + description: "Get data", + mimeType: "application/json", + outputSchema: { + input: { + type: "http", + method: "GET", + discoverable: true, + }, + output: null, + }, + payTo: "0x...", + maxTimeoutSeconds: 300, + asset: "0x...", + extra: {}, + }; + + const info = extractDiscoveryInfoV1(v1Requirements as any); + expect(info).not.toBeNull(); + expect(info!.input.method).toBe("GET"); + expect(info!.input.type).toBe("http"); + }); + + it("should extract discovery info from v1 GET with queryParams", () => { + const v1Requirements = { + scheme: "exact", + network: "eip155:8453" as any, + maxAmountRequired: "10000", + resource: "https://api.example.com/list", + description: "List items", + mimeType: "application/json", + outputSchema: { + input: { + discoverable: true, + method: "GET", + queryParams: { + limit: "integer parameter", + offset: "integer parameter", + }, + type: "http", + }, + output: { type: "array" }, + }, + payTo: "0x...", + maxTimeoutSeconds: 300, + asset: "0x...", + extra: {}, + }; + + const info = extractDiscoveryInfoV1(v1Requirements as any); + expect(info).not.toBeNull(); + expect(info!.input.method).toBe("GET"); + expect(info!.input.queryParams).toEqual({ + limit: "integer parameter", + offset: "integer parameter", + }); + }); + + it("should extract discovery info from v1 POST with bodyFields", () => { + const v1Requirements = { + scheme: "exact", + network: "eip155:8453" as any, + maxAmountRequired: "10000", + resource: "https://api.example.com/search", + description: "Search", + mimeType: "application/json", + outputSchema: { + input: { + bodyFields: { + query: { + description: "Search query", + required: true, + type: "string", + }, + }, + bodyType: "json", + discoverable: true, + method: "POST", + type: "http", + }, + }, + payTo: "0x...", + maxTimeoutSeconds: 120, + asset: "0x...", + extra: {}, + }; + + const info = extractDiscoveryInfoV1(v1Requirements as any); + expect(info).not.toBeNull(); + expect(info!.input.method).toBe("POST"); + expect((info as BodyDiscoveryInfo).input.bodyType).toBe("json"); + expect((info as BodyDiscoveryInfo).input.body).toEqual({ + query: { + description: "Search query", + required: true, + type: "string", + }, + }); + }); + + it("should extract discovery info from v1 POST with snake_case fields", () => { + const v1Requirements = { + scheme: "exact", + network: "eip155:8453" as any, + maxAmountRequired: "1000", + resource: "https://api.example.com/action", + description: "Action", + mimeType: "application/json", + outputSchema: { + input: { + body_fields: null, + body_type: null, + discoverable: true, + header_fields: { + "X-Budget": { + description: "Budget", + required: false, + type: "string", + }, + }, + method: "POST", + query_params: null, + type: "http", + }, + output: null, + }, + payTo: "0x...", + maxTimeoutSeconds: 60, + asset: "0x...", + extra: {}, + }; + + const info = extractDiscoveryInfoV1(v1Requirements as any); + expect(info).not.toBeNull(); + expect(info!.input.method).toBe("POST"); + expect(info!.input.headers).toEqual({ + "X-Budget": { + description: "Budget", + required: false, + type: "string", + }, + }); + }); + + it("should extract discovery info from v1 POST with bodyParams", () => { + const v1Requirements = { + scheme: "exact", + network: "eip155:8453" as any, + maxAmountRequired: "50000", + resource: "https://api.example.com/query", + description: "Query", + mimeType: "application/json", + outputSchema: { + input: { + bodyParams: { + question: { + description: "Question", + required: true, + type: "string", + maxLength: 500, + }, + }, + discoverable: true, + method: "POST", + type: "http", + }, + }, + payTo: "0x...", + maxTimeoutSeconds: 300, + asset: "0x...", + extra: {}, + }; + + const info = extractDiscoveryInfoV1(v1Requirements as any); + expect(info).not.toBeNull(); + expect(info!.input.method).toBe("POST"); + expect((info as BodyDiscoveryInfo).input.body).toEqual({ + question: { + description: "Question", + required: true, + type: "string", + maxLength: 500, + }, + }); + }); + + it("should extract discovery info from v1 POST with properties field", () => { + const v1Requirements = { + scheme: "exact", + network: "eip155:8453" as any, + maxAmountRequired: "80000", + resource: "https://api.example.com/chat", + description: "Chat", + mimeType: "application/json", + outputSchema: { + input: { + discoverable: true, + method: "POST", + properties: { + message: { + description: "Message", + type: "string", + }, + stream: { + description: "Stream", + type: "boolean", + }, + }, + required: ["message"], + type: "http", + }, + }, + payTo: "0x...", + maxTimeoutSeconds: 60, + asset: "0x...", + extra: {}, + }; + + const info = extractDiscoveryInfoV1(v1Requirements as any); + expect(info).not.toBeNull(); + expect(info!.input.method).toBe("POST"); + expect((info as BodyDiscoveryInfo).input.body).toEqual({ + message: { + description: "Message", + type: "string", + }, + stream: { + description: "Stream", + type: "boolean", + }, + }); + }); + + it("should handle v1 POST with no body content (minimal)", () => { + const v1Requirements = { + scheme: "exact", + network: "eip155:8453" as any, + maxAmountRequired: "10000", + resource: "https://api.example.com/action", + description: "Action", + mimeType: "application/json", + outputSchema: { + input: { + discoverable: true, + method: "POST", + type: "http", + }, + }, + payTo: "0x...", + maxTimeoutSeconds: 60, + asset: "0x...", + extra: {}, + }; + + const info = extractDiscoveryInfoV1(v1Requirements as any); + expect(info).not.toBeNull(); + expect(info!.input.method).toBe("POST"); + expect((info as BodyDiscoveryInfo).input.bodyType).toBe("json"); + expect((info as BodyDiscoveryInfo).input.body).toEqual({}); + }); + + it("should skip non-discoverable endpoints", () => { + const v1Requirements = { + scheme: "exact", + network: "eip155:8453" as any, + maxAmountRequired: "10000", + resource: "https://api.example.com/internal", + description: "Internal", + mimeType: "application/json", + outputSchema: { + input: { + discoverable: false, + method: "POST", + type: "http", + }, + }, + payTo: "0x...", + maxTimeoutSeconds: 60, + asset: "0x...", + extra: {}, + }; + + const info = extractDiscoveryInfoV1(v1Requirements as any); + expect(info).toBeNull(); + }); + + it("should handle missing outputSchema", () => { + const v1Requirements = { + scheme: "exact", + network: "eip155:8453" as any, + maxAmountRequired: "10000", + resource: "https://api.example.com/resource", + description: "Resource", + mimeType: "application/json", + outputSchema: {}, + payTo: "0x...", + maxTimeoutSeconds: 60, + asset: "0x...", + extra: {}, + }; + + const info = extractDiscoveryInfoV1(v1Requirements as any); + expect(info).toBeNull(); + }); + }); + + describe("Integration - Full workflow", () => { + it("should handle GET endpoint with output schema (e2e scenario)", () => { + // This reproduces the exact scenario from e2e tests + const extension = declareDiscoveryExtension({ + method: "GET", + input: {}, // No query params + inputSchema: { + properties: {}, + }, + output: { + example: { + message: "Protected endpoint accessed successfully", + timestamp: "2024-01-01T00:00:00Z", + }, + schema: { + properties: { + message: { type: "string" }, + timestamp: { type: "string" }, + }, + required: ["message", "timestamp"], + }, + }, + }); + + // Validate the extension + const validation = validateDiscoveryExtension(extension); + + // Debug: print validation errors if any + if (!validation.valid) { + console.log("Validation errors:", validation.errors); + console.log("Extension info:", JSON.stringify(extension.info, null, 2)); + console.log("Extension schema:", JSON.stringify(extension.schema, null, 2)); + } + + expect(validation.valid).toBe(true); + + // Extract info + const info = extractDiscoveryInfoFromExtension(extension, false); + expect(info.input.method).toBe("GET"); + expect(info.output?.example).toEqual({ + message: "Protected endpoint accessed successfully", + timestamp: "2024-01-01T00:00:00Z", + }); + }); + + it("should handle complete v2 server-to-facilitator workflow", () => { + // 1. Server declares extension + const extension = declareDiscoveryExtension({ + method: "POST", + input: { userId: "123", action: "create" }, + inputSchema: { + properties: { + userId: { type: "string" }, + action: { type: "string", enum: ["create", "update", "delete"] }, + }, + required: ["userId", "action"], + }, + bodyType: "json", + output: { + example: { success: true, id: "new-id" }, + }, + }); + + // 2. Server includes in PaymentRequired + const paymentRequired = { + x402Version: 2, + resource: { + url: "/api/action", + description: "Execute an action", + mimeType: "application/json", + }, + accepts: [], + extensions: { + [BAZAAR]: extension, + }, + }; + + // 3. Facilitator receives and validates + const bazaarExt = paymentRequired.extensions?.[BAZAAR] as DiscoveryExtension; + expect(bazaarExt).toBeDefined(); + + const validation = validateDiscoveryExtension(bazaarExt); + expect(validation.valid).toBe(true); + + // 4. Facilitator extracts info for cataloging using the extension directly + const info = extractDiscoveryInfoFromExtension(bazaarExt, false); + expect(info.input.method).toBe("POST"); + expect((info as BodyDiscoveryInfo).input.bodyType).toBe("json"); + expect((info as BodyDiscoveryInfo).input.body).toEqual({ userId: "123", action: "create" }); + expect(info.output?.example).toEqual({ success: true, id: "new-id" }); + + // Facilitator can now catalog this endpoint in the Bazaar + }); + + it("should handle v1-to-v2 transformation workflow", () => { + // V1 PaymentRequirements from real Bazaar data + const v1Requirements = { + scheme: "exact", + network: "eip155:8453" as any, + maxAmountRequired: "10000", + resource: "https://mesh.heurist.xyz/x402/agents/TokenResolverAgent/search", + description: "Find tokens by address, ticker/symbol, or token name", + mimeType: "application/json", + outputSchema: { + input: { + bodyFields: { + chain: { + description: "Optional chain hint", + type: "string", + }, + query: { + description: "Token search query", + required: true, + type: "string", + }, + type_hint: { + description: "Optional type hint", + enum: ["address", "symbol", "name"], + type: "string", + }, + }, + bodyType: "json", + discoverable: true, + method: "POST", + type: "http", + }, + }, + payTo: "0x7d9d1821d15B9e0b8Ab98A058361233E255E405D", + maxTimeoutSeconds: 120, + asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + extra: {}, + }; + + const v1Payload = { + x402Version: 1, + scheme: "exact", + network: "eip155:8453" as any, + payload: {}, + }; + + // Facilitator extracts v1 info and transforms to v2 + const info = extractDiscoveryInfo(v1Payload as any, v1Requirements as any); + + expect(info).not.toBeNull(); + expect(info!.input.method).toBe("POST"); + expect(info!.input.type).toBe("http"); + expect((info as BodyDiscoveryInfo).input.bodyType).toBe("json"); + expect((info as BodyDiscoveryInfo).input.body).toHaveProperty("query"); + expect((info as BodyDiscoveryInfo).input.body).toHaveProperty("chain"); + expect((info as BodyDiscoveryInfo).input.body).toHaveProperty("type_hint"); + }); + + it("should handle unified extraction for both v1 and v2", () => { + // V2 case - extensions are in PaymentPayload + const v2Extension = declareDiscoveryExtension({ + method: "GET", + input: { limit: 10 }, + inputSchema: { + properties: { + limit: { type: "number" }, + }, + }, + }); + + const v2Payload = { + x402Version: 2, + scheme: "exact", + network: "eip155:8453" as any, + payload: {}, + accepted: {} as any, + extensions: { + [BAZAAR]: v2Extension, + }, + }; + + const v2Info = extractDiscoveryInfo(v2Payload, {} as any); + + expect(v2Info).not.toBeNull(); + expect(v2Info!.input.method).toBe("GET"); + + // V1 case - discovery info is in PaymentRequirements.outputSchema + const v1Requirements = { + scheme: "exact", + network: "eip155:8453" as any, + maxAmountRequired: "10000", + resource: "https://api.example.com/list", + description: "List", + mimeType: "application/json", + outputSchema: { + input: { + discoverable: true, + method: "GET", + queryParams: { limit: "number" }, + type: "http", + }, + }, + payTo: "0x...", + maxTimeoutSeconds: 300, + asset: "0x...", + extra: {}, + }; + + const v1Payload = { + x402Version: 1, + scheme: "exact", + network: "eip155:8453" as any, + payload: {}, + }; + + const v1Info = extractDiscoveryInfo(v1Payload as any, v1Requirements as any); + + expect(v1Info).not.toBeNull(); + expect(v1Info!.input.method).toBe("GET"); + + // Both v1 and v2 return the same DiscoveryInfo structure + expect(typeof v2Info!.input).toBe(typeof v1Info!.input); + }); + }); +}); + diff --git a/typescript/packages/extensions/tsconfig.json b/typescript/packages/extensions/tsconfig.json new file mode 100644 index 000000000..54bc23c05 --- /dev/null +++ b/typescript/packages/extensions/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "lib": [ + "ES2020" + ], + "allowJs": false, + "checkJs": false + }, + "include": [ + "src", + "test/bazaar.test.ts" + ] +} \ No newline at end of file diff --git a/typescript/packages/extensions/tsup.config.ts b/typescript/packages/extensions/tsup.config.ts new file mode 100644 index 000000000..5384aa8ce --- /dev/null +++ b/typescript/packages/extensions/tsup.config.ts @@ -0,0 +1,29 @@ +import { defineConfig } from "tsup"; + +const baseConfig = { + entry: { + index: "src/index.ts", + "bazaar/index": "src/bazaar/index.ts", + "sign-in-with-x/index": "src/sign-in-with-x/index.ts", + }, + dts: { + resolve: true, + }, + sourcemap: true, + target: "es2020", +}; + +export default defineConfig([ + { + ...baseConfig, + format: "esm", + outDir: "dist/esm", + clean: true, + }, + { + ...baseConfig, + format: "cjs", + outDir: "dist/cjs", + clean: false, + }, +]); diff --git a/typescript/packages/x402-axios/vitest.config.ts b/typescript/packages/extensions/vitest.config.ts similarity index 100% rename from typescript/packages/x402-axios/vitest.config.ts rename to typescript/packages/extensions/vitest.config.ts diff --git a/typescript/packages/x402-fetch/.prettierignore b/typescript/packages/http/axios/.prettierignore similarity index 100% rename from typescript/packages/x402-fetch/.prettierignore rename to typescript/packages/http/axios/.prettierignore diff --git a/typescript/packages/x402-fetch/.prettierrc b/typescript/packages/http/axios/.prettierrc similarity index 100% rename from typescript/packages/x402-fetch/.prettierrc rename to typescript/packages/http/axios/.prettierrc diff --git a/typescript/packages/http/axios/README.md b/typescript/packages/http/axios/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/typescript/packages/http/axios/TODO.md b/typescript/packages/http/axios/TODO.md new file mode 100644 index 000000000..ed05fd615 --- /dev/null +++ b/typescript/packages/http/axios/TODO.md @@ -0,0 +1,9 @@ +# @x402/axios + +## TODO + +The `@x402/axios` package provides an Axios interceptor for handling **x402 Payment Required** responses using the x402 protocol. + +It replaces the legacy `x402-axios` package and leverages the shared `x402HTTPClient` from `@x402/core` to centralize payment handling logic. + +**Tip** Use the legacy `x402-axios` package as a basis, but re-implement the x402 logic following `@x402/fetch` as a reference. \ No newline at end of file diff --git a/typescript/packages/x402-next/eslint.config.js b/typescript/packages/http/axios/eslint.config.js similarity index 100% rename from typescript/packages/x402-next/eslint.config.js rename to typescript/packages/http/axios/eslint.config.js diff --git a/typescript/packages/http/axios/package.json b/typescript/packages/http/axios/package.json new file mode 100644 index 000000000..58803a751 --- /dev/null +++ b/typescript/packages/http/axios/package.json @@ -0,0 +1,60 @@ +{ + "name": "@x402/axios", + "version": "2.0.0", + "main": "./dist/cjs/index.js", + "module": "./dist/esm/index.js", + "types": "./dist/index.d.ts", + "scripts": { + "start": "tsx --env-file=.env index.ts", + "test": "vitest run", + "test:watch": "vitest", + "build": "tsup", + "watch": "tsc --watch", + "format": "prettier -c .prettierrc --write \"**/*.{ts,js,cjs,json,md}\"", + "format:check": "prettier -c .prettierrc --check \"**/*.{ts,js,cjs,json,md}\"", + "lint": "eslint . --ext .ts --fix", + "lint:check": "eslint . --ext .ts" + }, + "keywords": [], + "license": "Apache-2.0", + "author": "Coinbase Inc.", + "repository": "https://github.com/coinbase/x402", + "description": "x402 Payment Protocol", + "devDependencies": { + "@eslint/js": "^9.24.0", + "@types/node": "^22.13.4", + "@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", + "tsup": "^8.4.0", + "tsx": "^4.19.2", + "typescript": "^5.7.3", + "vite-tsconfig-paths": "^5.1.4", + "vitest": "^3.0.5", + "vite": "^6.2.6" + }, + "dependencies": { + "axios": "^1.7.9", + "@x402/core": "workspace:*", + "zod": "^3.24.2" + }, + "exports": { + ".": { + "import": { + "types": "./dist/esm/index.d.mts", + "default": "./dist/esm/index.mjs" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + } + } + }, + "files": [ + "dist" + ] +} diff --git a/typescript/packages/http/axios/src/index.test.ts b/typescript/packages/http/axios/src/index.test.ts new file mode 100644 index 000000000..f1b6de5b1 --- /dev/null +++ b/typescript/packages/http/axios/src/index.test.ts @@ -0,0 +1,12 @@ +import { describe, it, expect } from "vitest"; + +describe("@x402/axios", () => { + it("should be defined", () => { + expect(true).toBe(true); + }); + + // TODO: Add actual tests for Axios adapter + it.todo("should create Axios interceptor"); + it.todo("should handle payment required responses"); + it.todo("should attach payment headers"); +}); diff --git a/typescript/packages/http/axios/src/index.ts b/typescript/packages/http/axios/src/index.ts new file mode 100644 index 000000000..2001445a9 --- /dev/null +++ b/typescript/packages/http/axios/src/index.ts @@ -0,0 +1,7 @@ +/** + * @module @x402/axios - x402 Payment Protocol Axios Extension + * + * This module provides Axios interceptor for handling x402 payment required responses. + */ + +export {}; diff --git a/typescript/packages/x402-hono/tsconfig.json b/typescript/packages/http/axios/tsconfig.json similarity index 68% rename from typescript/packages/x402-hono/tsconfig.json rename to typescript/packages/http/axios/tsconfig.json index d14a78d24..1b119d386 100644 --- a/typescript/packages/x402-hono/tsconfig.json +++ b/typescript/packages/http/axios/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.base.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "allowJs": false, "checkJs": false diff --git a/typescript/packages/coinbase-x402/tsup.config.ts b/typescript/packages/http/axios/tsup.config.ts similarity index 100% rename from typescript/packages/coinbase-x402/tsup.config.ts rename to typescript/packages/http/axios/tsup.config.ts diff --git a/typescript/packages/x402-express/vitest.config.ts b/typescript/packages/http/axios/vitest.config.ts similarity index 100% rename from typescript/packages/x402-express/vitest.config.ts rename to typescript/packages/http/axios/vitest.config.ts diff --git a/typescript/packages/x402-hono/.prettierignore b/typescript/packages/http/express/.prettierignore similarity index 100% rename from typescript/packages/x402-hono/.prettierignore rename to typescript/packages/http/express/.prettierignore diff --git a/typescript/packages/x402-hono/.prettierrc b/typescript/packages/http/express/.prettierrc similarity index 100% rename from typescript/packages/x402-hono/.prettierrc rename to typescript/packages/http/express/.prettierrc diff --git a/typescript/packages/http/express/README.md b/typescript/packages/http/express/README.md new file mode 100644 index 000000000..8b34e2e44 --- /dev/null +++ b/typescript/packages/http/express/README.md @@ -0,0 +1,233 @@ +# @x402/express + +Express middleware integration for the x402 Payment Protocol. This package provides a simple middleware function for adding x402 payment requirements to your Express.js applications. + +## Installation + +```bash +npm install @x402/express +``` + +## Quick Start + +```typescript +import express from "express"; +import { paymentMiddleware } from "@x402/express"; + +const app = express(); + +// Apply the payment middleware with your configuration +app.use(paymentMiddleware( + { + "/protected-route": { + price: "$0.10", + network: "base-sepolia", + config: { + description: "Access to premium content", + } + } + }, + // Optional: custom facilitator client + undefined, + // Optional: paywall configuration + { + cdpClientKey: "your-cdp-client-key", + appName: "Your App", + appLogo: "/logo.svg" + } +)); + +// Implement your protected route +app.get("/protected-route", + (req, res) => { + res.json({ message: "This content is behind a paywall" }); + } +); + +app.listen(3000); +``` + +## Configuration + +The `paymentMiddleware` function accepts three parameters: + +```typescript +paymentMiddleware( + routes: RoutesConfig, + facilitatorClients?: FacilitatorClient | FacilitatorClient[], + paywallConfig?: PaywallConfig +) +``` + +### Parameters + +1. **`routes`** (required): Route configurations for protected endpoints +2. **`facilitatorClients`** (optional): Custom facilitator client(s) for payment processing +3. **`paywallConfig`** (optional): Configuration for the built-in paywall UI + +See the sections below for detailed configuration options. + +## API Reference + +### ExpressAdapter + +The `ExpressAdapter` class implements the `HTTPAdapter` interface from `@x402/core`, providing Express-specific request handling: + +```typescript +class ExpressAdapter implements HTTPAdapter { + getHeader(name: string): string | undefined + getMethod(): string + getPath(): string + getUrl(): string + getAcceptHeader(): string + getUserAgent(): string +} +``` + +### Middleware Function + +```typescript +function paymentMiddleware( + routes: RoutesConfig, + facilitatorClients?: FacilitatorClient | FacilitatorClient[], + paywallConfig?: PaywallConfig +): (req: Request, res: Response, next: NextFunction) => Promise +``` + +Creates Express middleware that: +1. Instantiates an x402HTTPResourceService with the provided configuration +2. Checks if the incoming request matches a protected route +3. Validates payment headers if required +4. Returns payment instructions (402 status) if payment is missing or invalid +5. Processes the request if payment is valid +6. Handles settlement after successful response + +### Route Configuration + +Routes are passed as the first parameter to `paymentMiddleware`: + +```typescript +const routes: RoutesConfig = { + "/api/protected": { + price: "$0.10", + network: "base-sepolia", + config: { + description: "Premium API access", + maxTimeoutSeconds: 60 + } + } +}; + +app.use(paymentMiddleware(routes)); +``` + +### Paywall Configuration + +The middleware automatically displays a paywall UI when browsers request protected endpoints. + +**Quick setup:** + +```typescript +app.use( + paymentMiddleware( + routes, + undefined, // facilitatorClients (optional) + undefined, // schemes (optional) + { + // paywallConfig + cdpClientKey: "your-cdp-client-key", + appName: "Your App", + testnet: true, + }, + ), +); +``` + +This uses `@x402/paywall` if installed (full wallet UI), or falls back to basic HTML. + +**For advanced configuration** (builder pattern, network-specific bundles, custom handlers), see the [@x402/paywall README](../paywall/README.md). + +## Advanced Usage + +### Multiple Protected Routes + +```typescript +app.use(paymentMiddleware( + { + "/api/premium/*": { + price: "$1.00", + network: "base", + config: { + description: "Premium API access" + } + }, + "/api/data": { + price: "$0.50", + network: "base-sepolia", + config: { + description: "Data endpoint access", + maxTimeoutSeconds: 120 + } + } + } +)); +``` + +### Custom Facilitator Client + +If you need to use a custom facilitator service, pass it as the second parameter: + +```typescript +import { createFacilitatorClient } from "@x402/core"; + +const customFacilitator = createFacilitatorClient({ + url: "https://your-facilitator.com", + createAuthHeaders: async () => ({ + verify: { "Authorization": "Bearer your-token" }, + settle: { "Authorization": "Bearer your-token" } + }) +}); + +app.use(paymentMiddleware(routes, customFacilitator, paywallConfig)); +``` + + +## Migration from x402-express + +If you're migrating from the legacy `x402-express` package: + +1. **Update imports**: Change from `x402-express` to `@x402/express` +2. **Simplified API**: The new `paymentMiddleware` function handles server instantiation internally +3. **Parameter order**: Routes are now the first parameter, followed by optional facilitator and paywall config + +### Before (x402-express): +```typescript +import { paymentMiddleware } from "x402-express"; + +app.use(paymentMiddleware( + payTo, // First param was payTo address + routes, // Second param was routes + facilitator, // Third param was facilitator config + paywall // Fourth param was paywall config +)); +``` + +### After (@x402/express): +```typescript +import { paymentMiddleware } from "@x402/express"; + +app.use(paymentMiddleware( + routes, // First param is now routes (payTo is part of route config) + facilitator, // Second param is facilitator client (optional) + paywall // Third param is paywall config (optional) +)); +``` + +Note: The `payTo` address is now specified within each route configuration rather than as a separate parameter. + +## Resources + +- [x402 Protocol](https://x402.org) +- [x402 Core Documentation](https://github.com/your-org/x402/tree/main/typescript/packages/core) +- [CDP Documentation](https://docs.cdp.coinbase.com) +- [CDP Discord](https://discord.com/invite/cdp) diff --git a/typescript/packages/http/express/TODO.md b/typescript/packages/http/express/TODO.md new file mode 100644 index 000000000..38588d173 --- /dev/null +++ b/typescript/packages/http/express/TODO.md @@ -0,0 +1,33 @@ +# Express Middleware TODO + +## Reference Implementation Status + +Express serves as the **reference implementation** for x402 HTTP middleware. All other middleware implementations (Hono, Next.js, etc.) should use this as their canonical reference during the development of v2. + +## Development Process + +1. **Pilot Features Here First**: All SDK improvements and new features during v2 development will be implemented in Express first +2. **Mirror to Other Packages**: Once validated in Express, changes should be propagated to: + - Hono middleware + - Next.js middleware + - Any future middleware implementations + +## Responsibilities as Reference Implementation + +- Maintain clear, well-documented code that serves as an example +- Establish patterns and conventions for other middleware to follow +- Test edge cases and error handling comprehensively +- Provide migration guides when breaking changes occur + +## Notes for Other Implementations + +When implementing Hono, Next.js, or other middleware packages: +1. Review the Express implementation first +2. Match the API surface as closely as the framework allows +3. Ensure feature parity with Express +4. Document any framework-specific deviations with justification + +# TODO + +- Auto-register evm exact and svm exact, depending on those packages +- Expose hooks once added to x402HTTPResourceServer diff --git a/typescript/packages/x402-express/eslint.config.js b/typescript/packages/http/express/eslint.config.js similarity index 100% rename from typescript/packages/x402-express/eslint.config.js rename to typescript/packages/http/express/eslint.config.js diff --git a/typescript/packages/http/express/package.json b/typescript/packages/http/express/package.json new file mode 100644 index 000000000..523dd8b75 --- /dev/null +++ b/typescript/packages/http/express/package.json @@ -0,0 +1,72 @@ +{ + "name": "@x402/express", + "version": "2.0.0", + "main": "./dist/cjs/index.js", + "module": "./dist/esm/index.js", + "types": "./dist/index.d.ts", + "scripts": { + "start": "tsx --env-file=.env index.ts", + "test": "vitest run", + "test:watch": "vitest", + "build": "tsup", + "watch": "tsc --watch", + "format": "prettier -c .prettierrc --write \"**/*.{ts,js,cjs,json,md}\"", + "format:check": "prettier -c .prettierrc --check \"**/*.{ts,js,cjs,json,md}\"", + "lint": "eslint . --ext .ts --fix", + "lint:check": "eslint . --ext .ts" + }, + "keywords": [], + "license": "Apache-2.0", + "author": "Coinbase Inc.", + "repository": "https://github.com/coinbase/x402", + "description": "x402 Payment Protocol", + "devDependencies": { + "@eslint/js": "^9.24.0", + "@types/express": "^5.0.1", + "@types/node": "^22.13.4", + "@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", + "tsup": "^8.4.0", + "tsx": "^4.19.2", + "typescript": "^5.7.3", + "vite": "^6.2.6", + "vite-tsconfig-paths": "^5.1.4", + "vitest": "^3.0.5" + }, + "dependencies": { + "@solana/kit": "^2.1.1", + "@coinbase/cdp-sdk": "^1.22.0", + "express": "^4.18.2", + "viem": "^2.21.26", + "@x402/core": "workspace:^", + "zod": "^3.24.2" + }, + "peerDependencies": { + "@x402/paywall": "workspace:*" + }, + "peerDependenciesMeta": { + "@x402/paywall": { + "optional": true + } + }, + "exports": { + ".": { + "import": { + "types": "./dist/esm/index.d.mts", + "default": "./dist/esm/index.mjs" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + } + } + }, + "files": [ + "dist" + ] +} diff --git a/typescript/packages/http/express/src/index.test.ts b/typescript/packages/http/express/src/index.test.ts new file mode 100644 index 000000000..e207fc64c --- /dev/null +++ b/typescript/packages/http/express/src/index.test.ts @@ -0,0 +1,12 @@ +import { describe, it, expect } from "vitest"; + +describe("@x402/express", () => { + it("should be defined", () => { + expect(true).toBe(true); + }); + + // TODO: Add actual tests for Express adapter + it.todo("should create Express adapter"); + it.todo("should handle payment middleware"); + it.todo("should process HTTP requests"); +}); diff --git a/typescript/packages/http/express/src/index.ts b/typescript/packages/http/express/src/index.ts new file mode 100644 index 000000000..2116ad130 --- /dev/null +++ b/typescript/packages/http/express/src/index.ts @@ -0,0 +1,241 @@ +import { + HTTPAdapter, + HTTPRequestContext, + PaywallConfig, + PaywallProvider, + x402HTTPResourceService, + RoutesConfig, + FacilitatorClient, +} from "@x402/core/server"; +import { SchemeNetworkService, Network } from "@x402/core/types"; +import { NextFunction, Request, Response } from "express"; + +/** + * Express adapter implementation + */ +export class ExpressAdapter implements HTTPAdapter { + /** + * Creates a new ExpressAdapter instance. + * + * @param req - The Express request object + */ + constructor(private req: Request) {} + + /** + * Gets a header value from the request. + * + * @param name - The header name + * @returns The header value or undefined + */ + getHeader(name: string): string | undefined { + const value = this.req.header(name); + return Array.isArray(value) ? value[0] : value; + } + + /** + * Gets the HTTP method of the request. + * + * @returns The HTTP method + */ + getMethod(): string { + return this.req.method; + } + + /** + * Gets the path of the request. + * + * @returns The request path + */ + getPath(): string { + return this.req.path; + } + + /** + * Gets the full URL of the request. + * + * @returns The full request URL + */ + getUrl(): string { + return `${this.req.protocol}://${this.req.headers.host}${this.req.path}`; + } + + /** + * Gets the Accept header from the request. + * + * @returns The Accept header value or empty string + */ + getAcceptHeader(): string { + return this.req.header("Accept") || ""; + } + + /** + * Gets the User-Agent header from the request. + * + * @returns The User-Agent header value or empty string + */ + getUserAgent(): string { + return this.req.header("User-Agent") || ""; + } +} + +/** + * Configuration for registering a payment scheme with a specific network + */ +export interface SchemeRegistration { + /** + * The network identifier (e.g., 'eip155:84532', 'solana:mainnet') + */ + network: Network; + + /** + * The scheme server implementation for this network + */ + server: SchemeNetworkService; +} + +/** + * Express payment middleware for x402 protocol + * + * @param routes - Route configurations for protected endpoints + * @param facilitatorClients - Optional facilitator client(s) for payment processing + * @param schemes - Optional array of scheme registrations for server-side payment processing + * @param paywallConfig - Optional configuration for the built-in paywall UI + * @param paywall - Optional custom paywall provider (overrides default) + * @param initializeOnStart - Whether to initialize the server on startup + * @returns Express middleware handler + */ +export function paymentMiddleware( + routes: RoutesConfig, + facilitatorClients?: FacilitatorClient | FacilitatorClient[], + schemes?: SchemeRegistration[], + paywallConfig?: PaywallConfig, + paywall?: PaywallProvider, + initializeOnStart: boolean = true, +) { + // Create the x402 HTTP server instance + const server = new x402HTTPResourceService(routes, facilitatorClients); + + // Register all provided schemes + if (schemes) { + schemes.forEach(({ network, server: schemeServer }) => { + server.registerScheme(network, schemeServer); + }); + } + + // Register custom paywall provider if provided + if (paywall) { + server.registerPaywallProvider(paywall); + } + + if (initializeOnStart) { + server.initialize(); + } + + return async (req: Request, res: Response, next: NextFunction) => { + // Create adapter and context + const adapter = new ExpressAdapter(req); + const context: HTTPRequestContext = { + adapter, + path: req.path, + method: req.method, + paymentHeader: adapter.getHeader("payment-signature") || adapter.getHeader("x-payment"), + }; + + // Process payment requirement check + const result = await server.processHTTPRequest(context, paywallConfig); + + // Handle the different result types + switch (result.type) { + case "no-payment-required": + // No payment needed, proceed directly to the route handler + return next(); + + case "payment-error": + // Payment required but not provided or invalid + const { response } = result; + res.status(response.status); + Object.entries(response.headers).forEach(([key, value]) => { + res.setHeader(key, value); + }); + if (response.isHtml) { + res.send(response.body); + } else { + res.json(response.body || {}); + } + return; + + case "payment-verified": + // Payment is valid, need to wrap response for settlement + const { paymentPayload, paymentRequirements } = result; + + /* 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 + await next(); + + // If the response from the protected route is >= 400, do not settle payment + if (res.statusCode >= 400) { + res.end = originalEnd; + if (endArgs) { + originalEnd(...(endArgs as Parameters)); + } + return; + } + + try { + const settlementHeaders = await server.processSettlement( + paymentPayload, + paymentRequirements, + res.statusCode, + ); + + if (settlementHeaders) { + Object.entries(settlementHeaders).forEach(([key, value]) => { + res.setHeader(key, value); + }); + } + + // If settlement returns null or succeeds, continue with original response + } catch (error) { + console.error(error); + // If settlement fails and the response hasn't been sent yet, return an error + if (!res.headersSent) { + res.status(402).json({ + error: "Settlement failed", + details: error instanceof Error ? error.message : "Unknown error", + }); + return; + } + } finally { + res.end = originalEnd; + if (endArgs) { + originalEnd(...(endArgs as Parameters)); + } + } + return; + } + }; +} + +export type { + PaymentRequired, + PaymentRequirements, + PaymentPayload, + Network, + SchemeNetworkService, +} from "@x402/core/types"; + +export type { PaywallProvider, PaywallConfig } from "@x402/core/server"; diff --git a/typescript/packages/coinbase-x402/tsconfig.json b/typescript/packages/http/express/tsconfig.json similarity index 68% rename from typescript/packages/coinbase-x402/tsconfig.json rename to typescript/packages/http/express/tsconfig.json index d14a78d24..1b119d386 100644 --- a/typescript/packages/coinbase-x402/tsconfig.json +++ b/typescript/packages/http/express/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.base.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "allowJs": false, "checkJs": false diff --git a/typescript/packages/x402-axios/tsup.config.ts b/typescript/packages/http/express/tsup.config.ts similarity index 100% rename from typescript/packages/x402-axios/tsup.config.ts rename to typescript/packages/http/express/tsup.config.ts diff --git a/typescript/packages/x402-fetch/vitest.config.ts b/typescript/packages/http/express/vitest.config.ts similarity index 100% rename from typescript/packages/x402-fetch/vitest.config.ts rename to typescript/packages/http/express/vitest.config.ts diff --git a/typescript/packages/x402-next/.prettierignore b/typescript/packages/http/fetch/.prettierignore similarity index 100% rename from typescript/packages/x402-next/.prettierignore rename to typescript/packages/http/fetch/.prettierignore diff --git a/typescript/packages/x402-next/.prettierrc b/typescript/packages/http/fetch/.prettierrc similarity index 100% rename from typescript/packages/x402-next/.prettierrc rename to typescript/packages/http/fetch/.prettierrc diff --git a/typescript/packages/http/fetch/README.md b/typescript/packages/http/fetch/README.md new file mode 100644 index 000000000..3bfaf5c19 --- /dev/null +++ b/typescript/packages/http/fetch/README.md @@ -0,0 +1,166 @@ +# x402-fetch + +A utility package that extends the native `fetch` API to automatically handle 402 Payment Required responses using the x402 payment protocol v2. This package enables seamless integration of payment functionality into your applications when making HTTP requests. + +## Installation + +```bash +npm install @x402/fetch +``` + +## Quick Start + +```typescript +import { wrapFetchWithPayment } from "@x402/fetch"; +import { ExactEvmClient } from "@x402/evm"; +import { privateKeyToAccount } from "viem/accounts"; + +// Create an account +const account = privateKeyToAccount("0xYourPrivateKey"); + +// Wrap the fetch function with payment handling +const fetchWithPayment = wrapFetchWithPayment(fetch, { + schemes: [ + { + network: "eip155:8453", // Base Sepolia + client: new ExactEvmClient(account), + }, + ], +}); + +// Make a request that may require payment +const response = await fetchWithPayment("https://api.example.com/paid-endpoint", { + method: "GET", +}); + +const data = await response.json(); +``` + +## API + +### `wrapFetchWithPayment(fetch, config)` + +Wraps the native fetch API to handle 402 Payment Required responses automatically. + +#### Parameters + +- `fetch`: The fetch function to wrap (typically `globalThis.fetch`) +- `config`: Configuration object with the following properties: + - `schemes`: Array of scheme registrations, each containing: + - `network`: Network identifier (e.g., 'eip155:8453', 'solana:mainnet', 'eip155:*' for wildcards) + - `client`: The scheme client implementation (e.g., `ExactEvmClient`, `SolanaExactScheme`) + - `x402Version`: Optional protocol version (defaults to 2, set to 1 for legacy support) + - `paymentRequirementsSelector`: Optional function to select payment requirements from multiple options + +#### 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. Creating a payment header using the configured scheme client +4. Retrying the request with the payment header + +## Examples + +### Basic Usage with EVM + +```typescript +import { config } from "dotenv"; +import { wrapFetchWithPayment, decodePaymentResponseHeader } from "@x402/fetch"; +import { privateKeyToAccount } from "viem/accounts"; +import { ExactEvmClient } from "@x402/evm"; + +config(); + +const { EVM_PRIVATE_KEY, API_URL } = process.env; + +const account = privateKeyToAccount(EVM_PRIVATE_KEY as `0x${string}`); + +const fetchWithPayment = wrapFetchWithPayment(fetch, { + schemes: [ + { + network: "eip155:*", // Support all EVM chains + client: new ExactEvmClient(account), + }, + ], +}); + +// Make a request to a paid API endpoint +fetchWithPayment(API_URL, { + method: "GET", +}) + .then(async response => { + const data = await response.json(); + + // Optionally decode the payment response header + const paymentResponse = response.headers.get("PAYMENT-RESPONSE"); + if (paymentResponse) { + const decoded = decodePaymentResponseHeader(paymentResponse); + console.log("Payment details:", decoded); + } + + console.log("Response data:", data); + }) + .catch(error => { + console.error(error); + }); +``` + +### Multi-Chain Support + +```typescript +import { wrapFetchWithPayment } from "@x402/fetch"; +import { ExactEvmClient } from "@x402/evm"; +import { SolanaExactScheme } from "@x402/solana"; + +const fetchWithPayment = wrapFetchWithPayment(fetch, { + schemes: [ + // EVM chains + { + network: "eip155:8453", // Base Sepolia + client: new ExactEvmClient(evmAccount), + }, + { + network: "eip155:1", // Ethereum Mainnet with v1 protocol + client: new ExactEvmClient(evmAccount), + x402Version: 1, // Use legacy v1 protocol + }, + // Solana + { + network: "solana:mainnet", + client: new SolanaExactScheme(solanaWallet), + }, + ], +}); +``` + +### Custom Payment Requirements Selector + +```typescript +import { wrapFetchWithPayment, type SelectPaymentRequirements } from "@x402/fetch"; + +// Custom selector that prefers the cheapest option +const selectCheapestOption: SelectPaymentRequirements = (version, accepts) => { + if (!accepts || accepts.length === 0) { + throw new Error("No payment options available"); + } + + // Sort by value and return the cheapest + const sorted = [...accepts].sort((a, b) => + BigInt(a.value) - BigInt(b.value) + ); + + return sorted[0]; +}; + +const fetchWithPayment = wrapFetchWithPayment(fetch, { + schemes: [ + { + network: "eip155:8453", + client: new ExactEvmClient(account), + }, + ], + paymentRequirementsSelector: selectCheapestOption, +}); +``` + diff --git a/typescript/packages/http/fetch/TODO.md b/typescript/packages/http/fetch/TODO.md new file mode 100644 index 000000000..e2250cb3c --- /dev/null +++ b/typescript/packages/http/fetch/TODO.md @@ -0,0 +1,34 @@ +# Fetch Client TODO + +## Reference Implementation Status + +Fetch serves as the **reference implementation** for x402 HTTP clients. All other client implementations (Axios, native HTTP clients, etc.) should use this as their canonical reference during the development of v2. + +## Development Process + +1. **Pilot Features Here First**: All client SDK improvements and new features during v2 development will be implemented in Fetch first +2. **Mirror to Other Packages**: Once validated in Fetch, changes should be propagated to: + - Axios client + - Native HTTP clients + - Any future client implementations + +## Responsibilities as Reference Implementation + +- Maintain clear, well-documented code that serves as an example +- Establish patterns and conventions for other clients to follow +- Test edge cases and error handling comprehensively +- Provide migration guides when breaking changes occur +- Define standard client behaviors (retries, timeouts, error handling) + +## Notes for Other Implementations + +When implementing Axios or other client packages: +1. Review the Fetch implementation first +2. Match the API surface as closely as the library allows +3. Ensure feature parity with Fetch +4. Document any library-specific deviations with justification + +# TODO + +- Auto-register evm exact and svm exact, depending on those packages +- Add support for adding policies \ No newline at end of file diff --git a/typescript/packages/x402-fetch/eslint.config.js b/typescript/packages/http/fetch/eslint.config.js similarity index 100% rename from typescript/packages/x402-fetch/eslint.config.js rename to typescript/packages/http/fetch/eslint.config.js diff --git a/typescript/packages/http/fetch/package.json b/typescript/packages/http/fetch/package.json new file mode 100644 index 000000000..352045449 --- /dev/null +++ b/typescript/packages/http/fetch/package.json @@ -0,0 +1,60 @@ +{ + "name": "@x402/fetch", + "version": "2.0.0", + "main": "./dist/cjs/index.js", + "module": "./dist/esm/index.js", + "types": "./dist/index.d.ts", + "scripts": { + "start": "tsx --env-file=.env index.ts", + "test": "vitest run", + "test:watch": "vitest", + "build": "tsup", + "watch": "tsc --watch", + "format": "prettier -c .prettierrc --write \"**/*.{ts,js,cjs,json,md}\"", + "format:check": "prettier -c .prettierrc --check \"**/*.{ts,js,cjs,json,md}\"", + "lint": "eslint . --ext .ts --fix", + "lint:check": "eslint . --ext .ts" + }, + "keywords": [], + "license": "Apache-2.0", + "author": "Coinbase Inc.", + "repository": "https://github.com/coinbase/x402", + "description": "x402 Payment Protocol Fetch Extension", + "devDependencies": { + "@types/node": "^22.13.4", + "@eslint/js": "^9.24.0", + "eslint": "^9.24.0", + "eslint-plugin-jsdoc": "^50.6.9", + "eslint-plugin-prettier": "^5.2.6", + "@typescript-eslint/eslint-plugin": "^8.29.1", + "@typescript-eslint/parser": "^8.29.1", + "eslint-plugin-import": "^2.31.0", + "prettier": "3.5.2", + "tsup": "^8.4.0", + "tsx": "^4.19.2", + "typescript": "^5.7.3", + "vite-tsconfig-paths": "^5.1.4", + "vitest": "^3.0.5", + "vite": "^6.2.6" + }, + "dependencies": { + "viem": "^2.21.26", + "zod": "^3.24.2", + "@x402/core": "workspace:^" + }, + "exports": { + ".": { + "import": { + "types": "./dist/esm/index.d.mts", + "default": "./dist/esm/index.mjs" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + } + } + }, + "files": [ + "dist" + ] +} diff --git a/typescript/packages/http/fetch/src/index.test.ts b/typescript/packages/http/fetch/src/index.test.ts new file mode 100644 index 000000000..b4ded24ac --- /dev/null +++ b/typescript/packages/http/fetch/src/index.test.ts @@ -0,0 +1,12 @@ +import { describe, it, expect } from "vitest"; + +describe("@x402/fetch", () => { + it("should be defined", () => { + expect(true).toBe(true); + }); + + // TODO: Add actual tests for Fetch adapter + it.todo("should wrap fetch API"); + it.todo("should handle payment required responses"); + it.todo("should retry with payment"); +}); diff --git a/typescript/packages/http/fetch/src/index.ts b/typescript/packages/http/fetch/src/index.ts new file mode 100644 index 000000000..23827c6ef --- /dev/null +++ b/typescript/packages/http/fetch/src/index.ts @@ -0,0 +1,192 @@ +import { x402HTTPClient, type SelectPaymentRequirements } from "@x402/core/client"; +import { type PaymentRequired, type Network } from "@x402/core/types"; +import { type SchemeNetworkClient } from "@x402/core/types"; + +/** + * Configuration for registering a payment scheme with a specific network + */ +export interface SchemeRegistration { + /** + * The network identifier (e.g., 'eip155:8453', 'solana:mainnet') + */ + network: Network; + + /** + * The scheme client implementation for this network + */ + client: SchemeNetworkClient; + + /** + * The x402 protocol version to use for this scheme + * + * @default 2 + */ + x402Version?: number; +} + +/** + * Configuration options for the fetch wrapper + */ +export interface FetchWrapperConfig { + /** + * Array of scheme registrations defining which payment methods are supported + */ + schemes: SchemeRegistration[]; + + /** + * Custom payment requirements selector function + * If not provided, uses the default selector (first available option) + */ + paymentRequirementsSelector?: SelectPaymentRequirements; +} + +/** + * Enables the payment of APIs using the x402 payment protocol v2. + * + * This function wraps the native fetch API to automatically handle 402 Payment Required responses + * by creating and sending payment headers. It will: + * 1. Make the initial request + * 2. If a 402 response is received, parse the payment requirements + * 3. Create a payment header using the configured x402HTTPClient + * 4. Retry the request with the payment header + * + * @param fetch - The fetch function to wrap (typically globalThis.fetch) + * @param config - Configuration options including scheme registrations and selectors + * @returns A wrapped fetch function that handles 402 responses automatically + * + * @example + * ```typescript + * import { wrapFetchWithPayment } from '@x402/fetch'; + * import { EVMExactScheme } from '@x402/evm'; + * import { SolanaExactScheme } from '@x402/solana'; + * + * const fetchWithPay = wrapFetchWithPayment(fetch, { + * schemes: [ + * { network: 'eip155:8453', client: new EVMExactScheme({ signer: evmWallet }) }, + * { network: 'solana:mainnet', client: new SolanaExactScheme({ signer: solanaWallet }) }, + * { network: 'eip155:1', client: new EVMExactScheme({ signer: evmWallet }), x402Version: 1 } + * ] + * }); + * + * // Make a request that may require payment + * const response = await fetchWithPay('https://api.example.com/paid-endpoint'); + * ``` + * + * @throws {Error} If no schemes are provided + * @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 wrapFetchWithPayment(fetch: typeof globalThis.fetch, config: FetchWrapperConfig) { + const { schemes, paymentRequirementsSelector } = config; + + if (!schemes || schemes.length === 0) { + throw new Error("At least one scheme registration is required"); + } + + // Create and configure the x402HTTPClient + const client = new x402HTTPClient(paymentRequirementsSelector); + + // Register all provided schemes + schemes.forEach(({ network, client: schemeClient, x402Version = 2 }) => { + if (x402Version === 1) { + client.registerSchemeV1(network, schemeClient); + } else { + client.registerScheme(network, schemeClient); + } + }); + + return async (input: RequestInfo, init?: RequestInit) => { + const response = await fetch(input, init); + + if (response.status !== 402) { + return response; + } + + // Parse payment requirements from response + let paymentRequired: PaymentRequired; + try { + const responseHeaders: Record = {}; + response.headers.forEach((value, key) => { + responseHeaders[key.toUpperCase()] = value; + }); + + // Try to get from headers first (v2), then from body (v1) + let body: PaymentRequired | undefined; + try { + const responseText = await response.text(); + if (responseText) { + body = JSON.parse(responseText) as PaymentRequired; + } + } catch { + // Ignore JSON parse errors - might be header-only response + } + + paymentRequired = client.getPaymentRequiredResponse(responseHeaders, body); + } catch (error) { + throw new Error( + `Failed to parse payment requirements: ${error instanceof Error ? error.message : "Unknown error"}`, + ); + } + + // Select payment requirements using the client's logic + const selectedPaymentRequirements = client.selectPaymentRequirements( + paymentRequired.x402Version, + paymentRequired.accepts, + ); + + // Create payment payload (copy extensions from PaymentRequired) + let paymentPayload; + try { + paymentPayload = await client.createPaymentPayload( + paymentRequired.x402Version, + selectedPaymentRequirements, + paymentRequired.extensions, + ); + } catch (error) { + throw new Error( + `Failed to create payment payload: ${error instanceof Error ? error.message : "Unknown error"}`, + ); + } + + // Encode payment header + const paymentHeaders = client.encodePaymentSignatureHeader(paymentPayload); + + // Ensure we have request init + if (!init) { + throw new Error("Missing fetch request configuration"); + } + + // Check if this is already a retry to prevent infinite loops + if ((init as { __is402Retry?: boolean }).__is402Retry) { + throw new Error("Payment already attempted"); + } + + // Create new request with payment header + const newInit = { + ...init, + headers: { + ...(init.headers || {}), + ...paymentHeaders, + "Access-Control-Expose-Headers": "PAYMENT-RESPONSE,X-PAYMENT-RESPONSE", + }, + __is402Retry: true, + }; + + // Retry the request with payment + const secondResponse = await fetch(input, newInit); + return secondResponse; + }; +} + +// Re-export types and utilities for convenience +export type { SelectPaymentRequirements } from "@x402/core/client"; +export type { + PaymentRequired, + PaymentRequirements, + PaymentPayload, + Network, +} from "@x402/core/types"; +export type { SchemeNetworkClient } from "@x402/core/types"; +export { decodePaymentResponseHeader } from "@x402/core/http"; +export { x402HTTPClient } from "@x402/core/client"; diff --git a/typescript/packages/x402-fetch/tsconfig.json b/typescript/packages/http/fetch/tsconfig.json similarity index 72% rename from typescript/packages/x402-fetch/tsconfig.json rename to typescript/packages/http/fetch/tsconfig.json index 7663a6058..117765590 100644 --- a/typescript/packages/x402-fetch/tsconfig.json +++ b/typescript/packages/http/fetch/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.base.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "allowJs": false, "checkJs": false, diff --git a/typescript/packages/x402-express/tsup.config.ts b/typescript/packages/http/fetch/tsup.config.ts similarity index 100% rename from typescript/packages/x402-express/tsup.config.ts rename to typescript/packages/http/fetch/tsup.config.ts diff --git a/typescript/packages/x402-hono/vitest.config.ts b/typescript/packages/http/fetch/vitest.config.ts similarity index 100% rename from typescript/packages/x402-hono/vitest.config.ts rename to typescript/packages/http/fetch/vitest.config.ts diff --git a/typescript/packages/x402/.prettierignore b/typescript/packages/http/hono/.prettierignore similarity index 100% rename from typescript/packages/x402/.prettierignore rename to typescript/packages/http/hono/.prettierignore diff --git a/typescript/packages/x402/.prettierrc b/typescript/packages/http/hono/.prettierrc similarity index 100% rename from typescript/packages/x402/.prettierrc rename to typescript/packages/http/hono/.prettierrc diff --git a/typescript/packages/http/hono/README.md b/typescript/packages/http/hono/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/typescript/packages/http/hono/TODO.md b/typescript/packages/http/hono/TODO.md new file mode 100644 index 000000000..be5371b51 --- /dev/null +++ b/typescript/packages/http/hono/TODO.md @@ -0,0 +1,9 @@ +# @x402/hono + +## TODO + +The `@x402/hono` package provides middleware for handling **x402 Payment Required** responses using the x402 protocol. + +It replaces the legacy `x402-hono` package and leverages the shared `x402HTTPResourceService` from `@x402/core` to gate routes that require payment before access. + +**Tip** Use the legacy `x402-hono` package as a basis, but re-implement the x402 logic following `@x402/express` as a reference. \ No newline at end of file diff --git a/typescript/packages/coinbase-x402/eslint.config.js b/typescript/packages/http/hono/eslint.config.js similarity index 100% rename from typescript/packages/coinbase-x402/eslint.config.js rename to typescript/packages/http/hono/eslint.config.js diff --git a/typescript/packages/http/hono/package.json b/typescript/packages/http/hono/package.json new file mode 100644 index 000000000..858c3d7b4 --- /dev/null +++ b/typescript/packages/http/hono/package.json @@ -0,0 +1,60 @@ +{ + "name": "@x402/hono", + "version": "2.0.0", + "main": "./dist/cjs/index.js", + "module": "./dist/esm/index.js", + "types": "./dist/index.d.ts", + "scripts": { + "start": "tsx --env-file=.env index.ts", + "test": "vitest run", + "test:watch": "vitest", + "build": "tsup", + "watch": "tsc --watch", + "format": "prettier -c .prettierrc --write \"**/*.{ts,js,cjs,json,md}\"", + "format:check": "prettier -c .prettierrc --check \"**/*.{ts,js,cjs,json,md}\"", + "lint": "eslint . --ext .ts --fix", + "lint:check": "eslint . --ext .ts" + }, + "keywords": [], + "license": "Apache-2.0", + "author": "Coinbase Inc.", + "repository": "https://github.com/coinbase/x402", + "description": "x402 Payment Protocol", + "devDependencies": { + "@eslint/js": "^9.24.0", + "@types/node": "^22.13.4", + "@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", + "tsup": "^8.4.0", + "tsx": "^4.19.2", + "typescript": "^5.7.3", + "vite": "^6.2.6", + "vite-tsconfig-paths": "^5.1.4", + "vitest": "^3.0.5" + }, + "dependencies": { + "hono": "^4.7.1", + "@x402/core": "workspace:*", + "zod": "^3.24.2" + }, + "exports": { + ".": { + "import": { + "types": "./dist/esm/index.d.mts", + "default": "./dist/esm/index.mjs" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + } + } + }, + "files": [ + "dist" + ] +} diff --git a/typescript/packages/http/hono/src/index.test.ts b/typescript/packages/http/hono/src/index.test.ts new file mode 100644 index 000000000..696632db4 --- /dev/null +++ b/typescript/packages/http/hono/src/index.test.ts @@ -0,0 +1,12 @@ +import { describe, it, expect } from "vitest"; + +describe("@x402/hono", () => { + it("should be defined", () => { + expect(true).toBe(true); + }); + + // TODO: Add actual tests for Hono adapter + it.todo("should create Hono middleware"); + it.todo("should handle payment validation"); + it.todo("should process Hono context"); +}); diff --git a/typescript/packages/http/hono/src/index.ts b/typescript/packages/http/hono/src/index.ts new file mode 100644 index 000000000..da5c18926 --- /dev/null +++ b/typescript/packages/http/hono/src/index.ts @@ -0,0 +1,6 @@ +/** + * @module @x402/hono - x402 Payment Protocol Hono Extension + * This module provides Hono middleware for handling x402 payment required responses. + */ + +export {}; diff --git a/typescript/packages/x402-axios/tsconfig.json b/typescript/packages/http/hono/tsconfig.json similarity index 68% rename from typescript/packages/x402-axios/tsconfig.json rename to typescript/packages/http/hono/tsconfig.json index d14a78d24..1b119d386 100644 --- a/typescript/packages/x402-axios/tsconfig.json +++ b/typescript/packages/http/hono/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.base.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "allowJs": false, "checkJs": false diff --git a/typescript/packages/x402-fetch/tsup.config.ts b/typescript/packages/http/hono/tsup.config.ts similarity index 100% rename from typescript/packages/x402-fetch/tsup.config.ts rename to typescript/packages/http/hono/tsup.config.ts diff --git a/typescript/packages/x402-next/vitest.config.ts b/typescript/packages/http/hono/vitest.config.ts similarity index 100% rename from typescript/packages/x402-next/vitest.config.ts rename to typescript/packages/http/hono/vitest.config.ts diff --git a/typescript/packages/x402-axios/.prettierignore copy b/typescript/packages/http/next/.prettierignore similarity index 100% rename from typescript/packages/x402-axios/.prettierignore copy rename to typescript/packages/http/next/.prettierignore diff --git a/typescript/packages/http/next/.prettierrc b/typescript/packages/http/next/.prettierrc new file mode 100644 index 000000000..ffb416b74 --- /dev/null +++ b/typescript/packages/http/next/.prettierrc @@ -0,0 +1,11 @@ +{ + "tabWidth": 2, + "useTabs": false, + "semi": true, + "singleQuote": false, + "trailingComma": "all", + "bracketSpacing": true, + "arrowParens": "avoid", + "printWidth": 100, + "proseWrap": "never" +} diff --git a/typescript/packages/http/next/README.md b/typescript/packages/http/next/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/typescript/packages/http/next/TODO.md b/typescript/packages/http/next/TODO.md new file mode 100644 index 000000000..934fcd399 --- /dev/null +++ b/typescript/packages/http/next/TODO.md @@ -0,0 +1,9 @@ +# @x402/next + +## TODO + +The `@x402/next` package provides middleware for handling **x402 Payment Required** responses using the x402 protocol. + +It replaces the legacy `x402-next` package and leverages the shared `x402HTTPResourceService` from `@x402/core` to gate API routes or pages that require payment before access. + +**Tip** Use the legacy `x402-next` package as a basis, but re-implement the x402 logic following `@x402/express` as a reference. \ No newline at end of file diff --git a/typescript/packages/http/next/eslint.config.js b/typescript/packages/http/next/eslint.config.js new file mode 100644 index 000000000..ca28b5c47 --- /dev/null +++ b/typescript/packages/http/next/eslint.config.js @@ -0,0 +1,72 @@ +import js from "@eslint/js"; +import ts from "@typescript-eslint/eslint-plugin"; +import tsParser from "@typescript-eslint/parser"; +import prettier from "eslint-plugin-prettier"; +import jsdoc from "eslint-plugin-jsdoc"; +import importPlugin from "eslint-plugin-import"; + +export default [ + { + ignores: ["dist/**", "node_modules/**"], + }, + { + files: ["**/*.ts"], + languageOptions: { + parser: tsParser, + sourceType: "module", + ecmaVersion: 2020, + globals: { + process: "readonly", + __dirname: "readonly", + module: "readonly", + require: "readonly", + Buffer: "readonly", + exports: "readonly", + setTimeout: "readonly", + clearTimeout: "readonly", + setInterval: "readonly", + clearInterval: "readonly", + }, + }, + plugins: { + "@typescript-eslint": ts, + prettier: prettier, + jsdoc: jsdoc, + import: importPlugin, + }, + rules: { + ...ts.configs.recommended.rules, + "import/first": "error", + "prettier/prettier": "error", + "@typescript-eslint/member-ordering": "error", + "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_$" }], + "jsdoc/tag-lines": ["error", "any", { startLines: 1 }], + "jsdoc/check-alignment": "error", + "jsdoc/no-undefined-types": "off", + "jsdoc/check-param-names": "error", + "jsdoc/check-tag-names": "error", + "jsdoc/check-types": "error", + "jsdoc/implements-on-classes": "error", + "jsdoc/require-description": "error", + "jsdoc/require-jsdoc": [ + "error", + { + require: { + FunctionDeclaration: true, + MethodDefinition: true, + ClassDeclaration: true, + ArrowFunctionExpression: false, + FunctionExpression: false, + }, + }, + ], + "jsdoc/require-param": "error", + "jsdoc/require-param-description": "error", + "jsdoc/require-param-type": "off", + "jsdoc/require-returns": "error", + "jsdoc/require-returns-description": "error", + "jsdoc/require-returns-type": "off", + "jsdoc/require-hyphen-before-param-description": ["error", "always"], + }, + }, +]; diff --git a/typescript/packages/http/next/package.json b/typescript/packages/http/next/package.json new file mode 100644 index 000000000..450b06a40 --- /dev/null +++ b/typescript/packages/http/next/package.json @@ -0,0 +1,63 @@ +{ + "name": "@x402/next", + "version": "2.0.0", + "main": "./dist/cjs/index.js", + "module": "./dist/esm/index.js", + "types": "./dist/index.d.ts", + "scripts": { + "start": "tsx --env-file=.env index.ts", + "test": "vitest run", + "test:watch": "vitest", + "build": "tsup", + "watch": "tsc --watch", + "format": "prettier -c .prettierrc --write \"**/*.{ts,js,cjs,json,md}\"", + "format:check": "prettier -c .prettierrc --check \"**/*.{ts,js,cjs,json,md}\"", + "lint": "eslint . --ext .ts --fix", + "lint:check": "eslint . --ext .ts" + }, + "keywords": [], + "license": "Apache-2.0", + "author": "Coinbase Inc.", + "repository": "https://github.com/coinbase/x402", + "description": "x402 Payment Protocol", + "devDependencies": { + "@eslint/js": "^9.24.0", + "@types/node": "^22.13.4", + "@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", + "tsup": "^8.4.0", + "tsx": "^4.19.2", + "typescript": "^5.7.3", + "vite": "^6.2.6", + "vite-tsconfig-paths": "^5.1.4", + "vitest": "^3.0.5" + }, + "dependencies": { + "@x402/core": "workspace:*", + "zod": "^3.24.2" + }, + "peerDependencies": { + "next": "^15.0.0" + }, + "type": "module", + "exports": { + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/cjs/index.d.cts", + "default": "./dist/cjs/index.cjs" + } + } + }, + "files": [ + "dist" + ] +} diff --git a/typescript/packages/http/next/src/index.test.ts b/typescript/packages/http/next/src/index.test.ts new file mode 100644 index 000000000..001e304f8 --- /dev/null +++ b/typescript/packages/http/next/src/index.test.ts @@ -0,0 +1,12 @@ +import { describe, it, expect } from "vitest"; + +describe("@x402/next", () => { + it("should be defined", () => { + expect(true).toBe(true); + }); + + // TODO: Add actual tests for Next.js adapter + it.todo("should create Next.js middleware"); + it.todo("should handle API routes"); + it.todo("should process server-side payments"); +}); diff --git a/typescript/packages/http/next/src/index.ts b/typescript/packages/http/next/src/index.ts new file mode 100644 index 000000000..d0482421a --- /dev/null +++ b/typescript/packages/http/next/src/index.ts @@ -0,0 +1,6 @@ +/** + * @module @x402/next - x402 Payment Protocol Next.js Extension + * This module provides Next.js middleware for handling x402 payment required responses. + */ + +export {}; diff --git a/typescript/packages/x402-express/tsconfig.json b/typescript/packages/http/next/tsconfig.json similarity index 68% rename from typescript/packages/x402-express/tsconfig.json rename to typescript/packages/http/next/tsconfig.json index d14a78d24..1b119d386 100644 --- a/typescript/packages/x402-express/tsconfig.json +++ b/typescript/packages/http/next/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.base.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "allowJs": false, "checkJs": false diff --git a/typescript/packages/x402-next/tsup.config.ts b/typescript/packages/http/next/tsup.config.ts similarity index 100% rename from typescript/packages/x402-next/tsup.config.ts rename to typescript/packages/http/next/tsup.config.ts diff --git a/typescript/packages/x402/vitest.config.ts b/typescript/packages/http/next/vitest.config.ts similarity index 100% rename from typescript/packages/x402/vitest.config.ts rename to typescript/packages/http/next/vitest.config.ts diff --git a/typescript/packages/http/paywall/.prettierignore b/typescript/packages/http/paywall/.prettierignore new file mode 100644 index 000000000..5bd240ba9 --- /dev/null +++ b/typescript/packages/http/paywall/.prettierignore @@ -0,0 +1,8 @@ +docs/ +dist/ +node_modules/ +coverage/ +.github/ +src/client +**/**/*.json +*.md \ No newline at end of file diff --git a/typescript/packages/http/paywall/.prettierrc b/typescript/packages/http/paywall/.prettierrc new file mode 100644 index 000000000..ffb416b74 --- /dev/null +++ b/typescript/packages/http/paywall/.prettierrc @@ -0,0 +1,11 @@ +{ + "tabWidth": 2, + "useTabs": false, + "semi": true, + "singleQuote": false, + "trailingComma": "all", + "bracketSpacing": true, + "arrowParens": "avoid", + "printWidth": 100, + "proseWrap": "never" +} diff --git a/typescript/packages/http/paywall/README.md b/typescript/packages/http/paywall/README.md new file mode 100644 index 000000000..eb3d4155e --- /dev/null +++ b/typescript/packages/http/paywall/README.md @@ -0,0 +1,256 @@ +# @x402/paywall + +Modular paywall UI for the x402 payment protocol with support for EVM and Solana networks. + +## Features + +- Pre-built paywall UI out of the box +- Wallet connection (MetaMask, Coinbase Wallet, Phantom, etc.) +- USDC balance checking +- Multi-network support (EVM + Solana) +- Tree-shakeable - only bundle what you need +- Fully customizable via builder pattern + +## Installation + +```bash +pnpm add @x402/paywall +``` + +## Bundle Sizes + +Choose the import that matches your needs: + +| Import | Size | Networks | Use Case | +|--------|------|----------|----------| +| `@x402/paywall` | 3.5MB | EVM + Solana | Multi-network apps | +| `@x402/paywall/evm` | 3.4MB | EVM only | Base, Ethereum, Polygon, etc. | +| `@x402/paywall/svm` | 1.0MB | Solana only | Solana apps | + +## Usage + +### Option 1: EVM Only + +```typescript +import { createPaywall } from '@x402/paywall'; +import { evmPaywall } from '@x402/paywall/evm'; + +const paywall = createPaywall() + .withNetwork(evmPaywall) + .withConfig({ + appName: 'My App', + cdpClientKey: 'your-cdp-key', + testnet: true + }) + .build(); + +// Use with Express +app.use(paymentMiddleware(routes, facilitators, schemes, undefined, paywall)); +``` + +### Option 2: Solana Only + +```typescript +import { createPaywall } from '@x402/paywall'; +import { svmPaywall } from '@x402/paywall/svm'; + +const paywall = createPaywall() + .withNetwork(svmPaywall) + .withConfig({ + appName: 'My Solana App', + testnet: true + }) + .build(); +``` + +### Option 3: Multi-Network + +```typescript +import { createPaywall } from '@x402/paywall'; +import { evmPaywall } from '@x402/paywall/evm'; +import { svmPaywall } from '@x402/paywall/svm'; + +const paywall = createPaywall() + .withNetwork(evmPaywall) // First-match priority + .withNetwork(svmPaywall) // Fallback option + .withConfig({ + appName: 'Multi-chain App', + cdpClientKey: 'your-key', + testnet: true + }) + .build(); +``` + +### Option 4: Legacy API (Backwards Compatible) + +```typescript +import { getPaywallHtml } from '@x402/paywall'; + +const html = getPaywallHtml({ + amount: 0.10, + paymentRequirements: [...], + currentUrl: "https://api.example.com/data", + testnet: true, + cdpClientKey: "your-key", + appName: "My App" +}); + +res.status(402).send(html); +``` + +## Configuration + +### PaywallConfig Options + +```typescript +interface PaywallConfig { + cdpClientKey?: string; // Coinbase Developer Platform API key + appName?: string; // App name shown in wallet connection + appLogo?: string; // App logo URL + sessionTokenEndpoint?: string; // Endpoint for onramp session tokens + currentUrl?: string; // URL of protected resource + testnet?: boolean; // Use testnet (default: true) +} +``` + +## How It Works + +### First-Match Selection + +When multiple networks are registered, the paywall uses **first-match selection**: + +1. Iterates through `paymentRequired.accepts` array +2. Finds the first payment requirement that has a registered handler +3. Uses that handler to generate the HTML + +**Example:** +```typescript +// Server returns multiple options +{ + "accepts": [ + { "network": "solana:5eykt...", ... }, // First + { "network": "eip155:8453", ... } // Second + ] +} + +// If both handlers registered, Solana is selected (it's first in accepts) +const paywall = createPaywall() + .withNetwork(evmPaywall) + .withNetwork(svmPaywall) + .build(); +``` + +### Supported Networks + +**EVM Networks** (via `evmPaywall`): +- v2 CAIP-2: `eip155:*` (e.g., `eip155:8453` for Base) +- v1 Legacy: `base`, `base-sepolia`, `polygon`, `avalanche`, etc. + +**Solana Networks** (via `svmPaywall`): +- v2 CAIP-2: `solana:*` (e.g., `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp`) +- v1 Legacy: `solana`, `solana-devnet` + +## With HTTP Middleware + +### Express + +```typescript +import express from 'express'; +import { paymentMiddleware } from '@x402/express'; +import { createPaywall } from '@x402/paywall'; +import { evmPaywall } from '@x402/paywall/evm'; + +const app = express(); + +const paywall = createPaywall() + .withNetwork(evmPaywall) + .withConfig({ appName: 'My API' }) + .build(); + +app.use(paymentMiddleware( + { "/api/premium": { price: "$0.10", network: "eip155:84532", payTo: "0x..." } }, + facilitators, + schemes, + undefined, + paywall +)); +``` + +### Automatic Detection + +If you provide `paywallConfig` without a custom paywall, `@x402/core` automatically: +1. Tries to load `@x402/paywall` if installed +2. Falls back to basic HTML if not installed + +```typescript +// Simple usage - auto-detects @x402/paywall +app.use(paymentMiddleware(routes, facilitators, schemes, { + appName: 'My App', + cdpClientKey: 'key', + testnet: true +})); +``` + +## Custom Network Handlers + +You can create custom handlers for new networks: + +```typescript +import { createPaywall, type PaywallNetworkHandler } from '@x402/paywall'; + +const suiPaywall: PaywallNetworkHandler = { + supports: (req) => req.network.startsWith('sui:'), + generateHtml: (req, paymentRequired, config) => { + return `...`; // Your custom Sui paywall + } +}; + +const paywall = createPaywall() + .withNetwork(evmPaywall) + .withNetwork(svmPaywall) + .withNetwork(suiPaywall) // Custom handler + .build(); +``` + +## Development + +### Build + +```bash +pnpm build:paywall # Generate HTML templates +pnpm build # Build TypeScript +``` + +### Test + +```bash +pnpm test # Run unit tests +``` + +## Migration from Legacy + +### From `x402/paywall` (v1) + +**Before:** +```typescript +import { getPaywallHtml } from 'x402/paywall'; +const html = getPaywallHtml({...}); +``` + +**After:** +```typescript +import { getPaywallHtml } from '@x402/paywall'; +const html = getPaywallHtml({...}); // Same API! +``` + +### Upgrade to Builder Pattern + +```typescript +import { createPaywall } from '@x402/paywall'; +import { evmPaywall } from '@x402/paywall/evm'; // Only EVM + +const paywall = createPaywall() + .withNetwork(evmPaywall) + .withConfig({...}) + .build(); +``` diff --git a/typescript/packages/http/paywall/TODO.md b/typescript/packages/http/paywall/TODO.md new file mode 100644 index 000000000..b2b36fb0f --- /dev/null +++ b/typescript/packages/http/paywall/TODO.md @@ -0,0 +1,57 @@ +# @x402/paywall + +## Overview + +The `@x402/paywall` package builds and exports the latest configurable **x402 paywall**. + +It replaces the baked-in paywall from v1 (previously exported as `x402/paywall` from the legacy npm package), creating a clearer separation of concerns and serving as a reference SDK for custom paywall implementations. + +This package is leveraged by `@x402/next`, `@x402/express`, and `@x402/hono` when returning **402 Payment Required** responses to browser clients. + +## Migration from Legacy Paywall + +### Legacy Package Structure +The original paywall was part of the monolithic `x402` npm package at: +- **Location**: `typescript/packages/legacy/x402/src/paywall/` +- **Export**: Available as `x402/paywall` in the v1 package +- **Build Process**: Custom esbuild setup that generates a self-contained HTML template with inlined JS/CSS + +### Current Legacy Implementation Details + +#### Core Files +1. **index.ts** - Main entry point that exports `getPaywallHtml()` function + - Accepts PaywallOptions (amount, paymentRequirements, URLs, config) + - Injects configuration into the HTML template via script tags + - Handles string escaping for safe injection + +2. **index.tsx** - React app entry point + - Initializes React root when window loads + - Renders PaywallApp wrapped in Providers + +3. **PaywallApp.tsx** - Main React component (~305 lines) + - Wallet connection via OnchainKit (Coinbase Smart Wallet, EOA, MetaMask, Phantom, Rabby, Trust, Frame) + - Payment processing using x402 exact scheme + - Balance checking and display + - Chain switching logic (Base/Base Sepolia) + - Onramp integration for mainnet + - Status management and error handling + +4. **build.ts** - Build script + - Uses esbuild with HTML plugin to bundle everything + - Generates a single HTML file with inlined JS/CSS + - Creates TypeScript constant (`PAYWALL_TEMPLATE`) for runtime use + - Also generates Python template for cross-language support + +#### Dependencies +- **UI/Wallet**: @coinbase/onchainkit, wagmi, viem +- **React**: react, react-dom +- **Build**: esbuild, @craftamap/esbuild-plugin-html +- **Styles**: OnchainKit styles + custom CSS + +## TODO - Initial Migration (Direct Lift) + +## Notes + +- The build process generates a completely self-contained HTML file (no external dependencies) +- Has Python template generation to support Python middleware. Needs Go. +- Consider maintaining backwards compatibility with v1 API surface diff --git a/typescript/packages/http/paywall/eslint.config.js b/typescript/packages/http/paywall/eslint.config.js new file mode 100644 index 000000000..2155bef9c --- /dev/null +++ b/typescript/packages/http/paywall/eslint.config.js @@ -0,0 +1,76 @@ +import js from "@eslint/js"; +import ts from "@typescript-eslint/eslint-plugin"; +import tsParser from "@typescript-eslint/parser"; +import prettier from "eslint-plugin-prettier"; +import jsdoc from "eslint-plugin-jsdoc"; +import importPlugin from "eslint-plugin-import"; + +export default [ + { + ignores: [ + "dist/**", + "node_modules/**", + "src/gen/**", + "src/dist/**", + "src/evm/gen/**", + "src/evm/dist/**", + "src/svm/gen/**", + "src/svm/dist/**", + ], + }, + { + files: ["**/*.ts"], + languageOptions: { + parser: tsParser, + sourceType: "module", + ecmaVersion: 2020, + globals: { + window: "readonly", + document: "readonly", + console: "readonly", + fetch: "readonly", + Response: "readonly", + process: "readonly", + __dirname: "readonly", + module: "readonly", + require: "readonly", + Buffer: "readonly", + BufferEncoding: "readonly", + exports: "readonly", + setTimeout: "readonly", + clearTimeout: "readonly", + setInterval: "readonly", + clearInterval: "readonly", + }, + }, + plugins: { + "@typescript-eslint": ts, + prettier: prettier, + jsdoc: jsdoc, + import: importPlugin, + }, + rules: { + ...ts.configs.recommended.rules, + "import/first": "error", + "prettier/prettier": "error", + "@typescript-eslint/member-ordering": "error", + "@typescript-eslint/no-unused-vars": ["error"], + "jsdoc/tag-lines": ["error", "any", { startLines: 1 }], + "jsdoc/check-alignment": "error", + "jsdoc/no-undefined-types": "off", + "jsdoc/check-param-names": "error", + "jsdoc/check-tag-names": "error", + "jsdoc/check-types": "error", + "jsdoc/implements-on-classes": "error", + "jsdoc/require-description": "error", + "jsdoc/require-jsdoc": "off", + "jsdoc/require-param": "off", + "jsdoc/require-param-description": "off", + "jsdoc/require-param-type": "off", + "jsdoc/require-returns": "error", + "jsdoc/require-returns-description": "error", + "jsdoc/require-returns-type": "off", + "jsdoc/require-hyphen-before-param-description": ["error", "always"], + }, + }, +]; diff --git a/typescript/packages/http/paywall/package.json b/typescript/packages/http/paywall/package.json new file mode 100644 index 000000000..6fb194fa6 --- /dev/null +++ b/typescript/packages/http/paywall/package.json @@ -0,0 +1,113 @@ +{ + "name": "@x402/paywall", + "version": "2.0.0", + "main": "./dist/cjs/index.js", + "module": "./dist/esm/index.js", + "types": "./dist/index.d.ts", + "type": "module", + "scripts": { + "start": "tsx --env-file=.env index.ts", + "test": "vitest run", + "test:watch": "vitest", + "build": "pnpm build:paywall && tsup", + "build:paywall": "tsx src/build.ts && tsx src/evm/build.ts && tsx src/svm/build.ts", + "watch": "tsc --watch", + "format": "prettier -c .prettierrc --write \"**/*.{ts,js,cjs,json,md}\"", + "format:check": "prettier -c .prettierrc --check \"**/*.{ts,js,cjs,json,md}\"", + "lint": "eslint . --ext .ts --fix", + "lint:check": "eslint . --ext .ts" + }, + "keywords": [ + "x402", + "paywall", + "payment", + "http-402" + ], + "license": "Apache-2.0", + "author": "Coinbase Inc.", + "repository": "https://github.com/coinbase/x402", + "description": "x402 Payment Protocol Paywall UI", + "devDependencies": { + "@craftamap/esbuild-plugin-html": "^0.9.0", + "@eslint/js": "^9.24.0", + "@types/node": "^22.13.4", + "@types/react": "^19", + "@types/react-dom": "^19", + "@typescript-eslint/eslint-plugin": "^8.29.1", + "@typescript-eslint/parser": "^8.29.1", + "buffer": "^6.0.3", + "esbuild": "^0.25.4", + "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", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "tsup": "^8.4.0", + "tsx": "^4.19.2", + "typescript": "^5.7.3", + "vite": "^6.2.6", + "vite-tsconfig-paths": "^5.1.4", + "vitest": "^3.0.5" + }, + "dependencies": { + "@coinbase/onchainkit": "^0.38.14", + "@scure/base": "^1.2.6", + "@solana-program/compute-budget": "^0.8.0", + "@solana-program/token": "^0.5.1", + "@solana-program/token-2022": "^0.4.2", + "@solana/kit": "^2.1.1", + "@solana/transaction-confirmation": "^2.1.1", + "@solana/wallet-standard-features": "^1.3.0", + "@wagmi/connectors": "^5.8.1", + "@wagmi/core": "^2.17.1", + "@wallet-standard/app": "^1.1.0", + "@wallet-standard/base": "^1.1.0", + "@wallet-standard/features": "^1.1.0", + "@x402/core": "workspace:*", + "x402": "workspace:*", + "viem": "^2.21.26", + "wagmi": "^2.15.6", + "zod": "^3.24.2" + }, + "peerDependencies": { + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "exports": { + ".": { + "import": { + "types": "./dist/esm/index.d.mts", + "default": "./dist/esm/index.mjs" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + } + }, + "./evm": { + "import": { + "types": "./dist/esm/evm/index.d.mts", + "default": "./dist/esm/evm/index.mjs" + }, + "require": { + "types": "./dist/cjs/evm/index.d.ts", + "default": "./dist/cjs/evm/index.js" + } + }, + "./svm": { + "import": { + "types": "./dist/esm/svm/index.d.mts", + "default": "./dist/esm/svm/index.mjs" + }, + "require": { + "types": "./dist/cjs/svm/index.d.ts", + "default": "./dist/cjs/svm/index.js" + } + } + }, + "files": [ + "dist" + ] +} diff --git a/typescript/packages/http/paywall/src/PaywallApp.tsx b/typescript/packages/http/paywall/src/PaywallApp.tsx new file mode 100644 index 000000000..12fcafc16 --- /dev/null +++ b/typescript/packages/http/paywall/src/PaywallApp.tsx @@ -0,0 +1,73 @@ +"use client"; + +import { useCallback, useMemo } from "react"; +import type { PaymentRequirements } from "x402/types"; +import { choosePaymentRequirement, isEvmNetwork, isSvmNetwork } from "./paywallUtils"; +import { EvmPaywall } from "./evm/EvmPaywall"; +import { SolanaPaywall } from "./svm/SolanaPaywall"; + +/** + * Main Paywall App Component + * + * @returns The PaywallApp component + */ +export function PaywallApp() { + const x402 = window.x402; + const testnet = x402.testnet ?? true; + + const paymentRequirement = useMemo(() => { + return choosePaymentRequirement(x402.paymentRequirements, testnet); + }, [testnet, x402.paymentRequirements]); + + const handleSuccessfulResponse = useCallback(async (response: Response) => { + const contentType = response.headers.get("content-type"); + if (contentType && contentType.includes("text/html")) { + document.documentElement.innerHTML = await response.text(); + } else { + const blob = await response.blob(); + const url = window.URL.createObjectURL(blob); + window.location.href = url; + } + }, []); + + if (!paymentRequirement) { + return ( +
+
+

Payment Required

+

Loading payment details...

+
+
+ ); + } + + if (isEvmNetwork(paymentRequirement.network)) { + return ( + + ); + } + + if (isSvmNetwork(paymentRequirement.network)) { + return ( + + ); + } + + return ( +
+
+

Payment Required

+

+ Unsupported network configuration for this paywall. Please contact the application + developer. +

+
+
+ ); +} diff --git a/typescript/packages/http/paywall/src/Providers.tsx b/typescript/packages/http/paywall/src/Providers.tsx new file mode 100644 index 000000000..af6c3d52e --- /dev/null +++ b/typescript/packages/http/paywall/src/Providers.tsx @@ -0,0 +1,52 @@ +import { OnchainKitProvider } from "@coinbase/onchainkit"; +import type { ReactNode } from "react"; +import { base, baseSepolia } from "viem/chains"; + +import { choosePaymentRequirement, isEvmNetwork } from "./paywallUtils"; + +type ProvidersProps = { + children: ReactNode; +}; + +/** + * Providers component for the paywall + * + * @param props - The component props + * @param props.children - The children of the Providers component + * @returns The Providers component + */ +export function Providers({ children }: ProvidersProps) { + const { testnet = true, cdpClientKey, appName, appLogo, paymentRequirements } = window.x402; + const selectedRequirement = choosePaymentRequirement(paymentRequirements, testnet); + + if (!isEvmNetwork(selectedRequirement.network)) { + return <>{children}; + } + + const chain = selectedRequirement.network === "base-sepolia" ? baseSepolia : base; + + return ( + + {children} + + ); +} diff --git a/typescript/packages/x402/src/paywall/baseTemplate.ts b/typescript/packages/http/paywall/src/baseTemplate.ts similarity index 100% rename from typescript/packages/x402/src/paywall/baseTemplate.ts rename to typescript/packages/http/paywall/src/baseTemplate.ts diff --git a/typescript/packages/x402/src/paywall/buffer-polyfill.ts b/typescript/packages/http/paywall/src/buffer-polyfill.ts similarity index 100% rename from typescript/packages/x402/src/paywall/buffer-polyfill.ts rename to typescript/packages/http/paywall/src/buffer-polyfill.ts diff --git a/typescript/packages/http/paywall/src/build.ts b/typescript/packages/http/paywall/src/build.ts new file mode 100644 index 000000000..4536bb8c0 --- /dev/null +++ b/typescript/packages/http/paywall/src/build.ts @@ -0,0 +1,99 @@ +import esbuild from "esbuild"; +import { htmlPlugin } from "@craftamap/esbuild-plugin-html"; +import fs from "fs"; +import path from "path"; +import { getBaseTemplate } from "./baseTemplate"; + +// This file only runs at build time and generates a template HTML file +// Template variables are handled at runtime, not build time + +const DIST_DIR = "src/dist"; +const OUTPUT_HTML = path.join(DIST_DIR, "paywall.html"); +const OUTPUT_TS = path.join("src/gen", "template.ts"); + +const options: esbuild.BuildOptions = { + entryPoints: ["src/index.tsx", "src/styles.css"], + bundle: true, + metafile: true, + outdir: DIST_DIR, + treeShaking: true, + minify: true, + format: "iife", + sourcemap: false, + platform: "browser", + target: "es2020", + jsx: "transform", + define: { + "process.env.NODE_ENV": '"development"', + global: "globalThis", + Buffer: "globalThis.Buffer", + }, + mainFields: ["browser", "module", "main"], + conditions: ["browser"], + plugins: [ + htmlPlugin({ + files: [ + { + entryPoints: ["src/index.tsx", "src/styles.css"], + filename: "paywall.html", + title: "Payment Required", + scriptLoading: "module", + inline: { + css: true, + js: true, + }, + htmlTemplate: getBaseTemplate(), + }, + ], + }), + ], + inject: ["./src/buffer-polyfill.ts"], + external: ["crypto"], +}; + +/** + * Builds the paywall HTML template with bundled JS and CSS. + * Creates a TypeScript file containing the template as a constant for runtime use. + */ +async function build() { + try { + // First, make sure the dist directory exists + if (!fs.existsSync(DIST_DIR)) { + fs.mkdirSync(DIST_DIR, { recursive: true }); + } + + // Make sure gen directory exists too + const genDir = path.dirname(OUTPUT_TS); + if (!fs.existsSync(genDir)) { + fs.mkdirSync(genDir, { recursive: true }); + } + + // Run esbuild to create the bundled HTML + await esbuild.build(options); + console.log("Build completed successfully!"); + + // Read the generated HTML file + if (fs.existsSync(OUTPUT_HTML)) { + const html = fs.readFileSync(OUTPUT_HTML, "utf8"); + + // Generate a TypeScript file with the template as a constant + const tsContent = `// THIS FILE IS AUTO-GENERATED - DO NOT EDIT +/** + * The pre-built, self-contained paywall template with inlined CSS and JS + */ +export const PAYWALL_TEMPLATE = ${JSON.stringify(html)}; +`; + + // Write the template.ts file + fs.writeFileSync(OUTPUT_TS, tsContent); + console.log(`Generated template.ts with bundled HTML (${html.length} bytes)`); + } else { + throw new Error(`Bundled HTML file not found at ${OUTPUT_HTML}`); + } + } catch (error) { + console.error("Build failed:", error); + process.exit(1); + } +} + +build(); diff --git a/typescript/packages/http/paywall/src/builder.test.ts b/typescript/packages/http/paywall/src/builder.test.ts new file mode 100644 index 000000000..89a12e92d --- /dev/null +++ b/typescript/packages/http/paywall/src/builder.test.ts @@ -0,0 +1,245 @@ +import { describe, expect, it } from "vitest"; +import { createPaywall, PaywallBuilder } from "./builder"; +import type { PaymentRequired } from "./types"; +import { evmPaywall } from "./evm"; +import { svmPaywall } from "./svm"; + +const mockPaymentRequired: PaymentRequired = { + x402Version: 2, + error: "Payment required", + resource: { + url: "https://example.com/api/data", + description: "Test Resource", + mimeType: "application/json", + }, + accepts: [ + { + scheme: "exact", + network: "base-sepolia", + asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", + amount: "100000", + payTo: "0x209693Bc6afc0C5328bA36FaF04C514EF312287C", + maxTimeoutSeconds: 60, + }, + ], +}; + +describe("PaywallBuilder", () => { + describe("createPaywall", () => { + it("creates a new PaywallBuilder instance", () => { + const builder = createPaywall(); + expect(builder).toBeInstanceOf(PaywallBuilder); + }); + }); + + describe("withConfig", () => { + it("sets configuration and returns builder for chaining", () => { + const builder = createPaywall(); + const result = builder.withConfig({ + appName: "Test App", + cdpClientKey: "test-key", + }); + expect(result).toBe(builder); // Same instance (chainable) + }); + + it("merges multiple config calls", () => { + const paywall = createPaywall() + .withConfig({ appName: "App 1" }) + .withConfig({ cdpClientKey: "key-1" }) + .build(); + + const html = paywall.generateHtml(mockPaymentRequired); + expect(html).toContain("App 1"); + expect(html).toContain("key-1"); + }); + + it("later configs override earlier ones", () => { + const paywall = createPaywall() + .withConfig({ appName: "First App" }) + .withConfig({ appName: "Second App" }) + .build(); + + const html = paywall.generateHtml(mockPaymentRequired); + expect(html).toContain("Second App"); + expect(html).not.toContain("First App"); + }); + }); + + describe("build", () => { + it("returns a PaywallProvider", () => { + const provider = createPaywall().build(); + expect(provider).toHaveProperty("generateHtml"); + expect(typeof provider.generateHtml).toBe("function"); + }); + + it("generates HTML with builder config", () => { + const paywall = createPaywall() + .withConfig({ + appName: "Builder Test", + testnet: true, + }) + .build(); + + const html = paywall.generateHtml(mockPaymentRequired); + expect(html).toContain(""); + expect(html).toContain("Builder Test"); + }); + + it("runtime config overrides builder config", () => { + const paywall = createPaywall() + .withConfig({ + appName: "Builder Config", + }) + .build(); + + const html = paywall.generateHtml(mockPaymentRequired, { + appName: "Runtime Config", + }); + + expect(html).toContain("Runtime Config"); + expect(html).not.toContain("Builder Config"); + }); + + it("merges builder config with runtime config", () => { + const paywall = createPaywall() + .withConfig({ + appName: "Test App", + testnet: true, + }) + .build(); + + const html = paywall.generateHtml(mockPaymentRequired, { + cdpClientKey: "runtime-key", + }); + + // Both builder and runtime configs should be present + expect(html).toContain("Test App"); // from builder + expect(html).toContain("runtime-key"); // from runtime + }); + }); + + describe("generateHtml", () => { + it("extracts amount from v2 payment requirements", () => { + const paywall = createPaywall().build(); + const html = paywall.generateHtml(mockPaymentRequired); + + // Amount should be parsed correctly (100000 / 1000000 = 0.1) + expect(html).toContain("window.x402"); + expect(html).toContain("0.1"); + }); + + it("extracts amount from v1 payment requirements", () => { + const v1PaymentRequired: PaymentRequired = { + ...mockPaymentRequired, + x402Version: 1, + accepts: [ + { + ...mockPaymentRequired.accepts[0], + maxAmountRequired: "50000", + }, + ], + }; + + const paywall = createPaywall().build(); + const html = paywall.generateHtml(v1PaymentRequired); + + // Amount should be 0.05 (50000 / 1000000) + expect(html).toContain("0.05"); + }); + + it("uses resource URL as currentUrl when not provided", () => { + const paywall = createPaywall().build(); + const html = paywall.generateHtml(mockPaymentRequired); + + expect(html).toContain("https://example.com/api/data"); + }); + + it("defaults to testnet when not specified", () => { + const paywall = createPaywall().build(); + const html = paywall.generateHtml(mockPaymentRequired); + + expect(html).toContain("testnet: true"); + }); + }); + + describe("withNetwork", () => { + it("registers network handler and returns builder for chaining", () => { + const builder = createPaywall(); + const result = builder.withNetwork(evmPaywall); + expect(result).toBe(builder); // Same instance (chainable) + }); + + it("uses first-match selection from accepts array", () => { + const multiNetworkPaymentRequired: PaymentRequired = { + ...mockPaymentRequired, + accepts: [ + // Solana is first in accepts array + { + scheme: "exact", + network: "solana:5eykt", + asset: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + amount: "100000", + payTo: "2wKupLR9q6wXYppw8Gr2NvWxKBUqm4PPJKkQfoxHEBg4", + maxTimeoutSeconds: 60, + }, + { + scheme: "exact", + network: "eip155:8453", + asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + amount: "100000", + payTo: "0x209693Bc6afc0C5328bA36FaF04C514EF312287C", + maxTimeoutSeconds: 60, + }, + ], + }; + + const paywall = createPaywall().withNetwork(evmPaywall).withNetwork(svmPaywall).build(); + + const html = paywall.generateHtml(multiNetworkPaymentRequired); + + // Should match first requirement in accepts array (Solana) + expect(html).toMatch(/SVM Paywall/); + }); + + it("falls back to default when no handler matches", () => { + const customNetworkRequired: PaymentRequired = { + ...mockPaymentRequired, + accepts: [ + { + scheme: "exact", + network: "unknown:network", + asset: "0x123", + amount: "100000", + payTo: "0x456", + maxTimeoutSeconds: 60, + }, + ], + }; + + const paywall = createPaywall().withNetwork(evmPaywall).withNetwork(svmPaywall).build(); + + const html = paywall.generateHtml(customNetworkRequired); + + // Should fall back to default paywall + expect(html).toContain(""); + }); + + it("only uses network handler when registered", () => { + const evmOnlyPaywall = createPaywall().withNetwork(evmPaywall).build(); + + const html = evmOnlyPaywall.generateHtml(mockPaymentRequired); + + expect(html).toContain(""); + }); + + it("can chain multiple networks", () => { + const paywall = createPaywall() + .withNetwork(evmPaywall) + .withNetwork(svmPaywall) + .withConfig({ appName: "Multi-chain App" }) + .build(); + + expect(paywall).toHaveProperty("generateHtml"); + }); + }); +}); diff --git a/typescript/packages/http/paywall/src/builder.ts b/typescript/packages/http/paywall/src/builder.ts new file mode 100644 index 000000000..dc12c8997 --- /dev/null +++ b/typescript/packages/http/paywall/src/builder.ts @@ -0,0 +1,112 @@ +import { getPaywallHtml } from "./paywall"; +import type { + PaywallConfig, + PaywallProvider, + PaymentRequired, + PaywallNetworkHandler, +} from "./types"; + +/** + * Builder for creating configured paywall providers + */ +export class PaywallBuilder { + private config: PaywallConfig = {}; + private handlers: PaywallNetworkHandler[] = []; + + /** + * Register a network-specific paywall handler + * + * @param handler - Network handler to register + * @returns This builder instance for chaining + */ + withNetwork(handler: PaywallNetworkHandler): this { + this.handlers.push(handler); + return this; + } + + /** + * Set configuration options for the paywall + * + * @param config - Paywall configuration options + * @returns This builder instance for chaining + */ + withConfig(config: PaywallConfig): this { + this.config = { ...this.config, ...config }; + return this; + } + + /** + * Build the paywall provider + * + * @returns A configured PaywallProvider instance + */ + build(): PaywallProvider { + const builderConfig = this.config; + const handlers = this.handlers; + + return { + generateHtml: (paymentRequired: PaymentRequired, runtimeConfig?: PaywallConfig): string => { + // Merge builder config with runtime config (runtime takes precedence) + const finalConfig = { ...builderConfig, ...runtimeConfig }; + + // If network handlers are registered, use first-match selection + if (handlers.length > 0) { + for (const requirement of paymentRequired.accepts) { + const handler = handlers.find(h => + h.supports(paymentRequired.x402Version, requirement), + ); + if (handler) { + return handler.generateHtml(requirement, paymentRequired, finalConfig); + } + } + // No handler matched, fall through to default + } + + // Default: Use the full paywall (includes both EVM and Solana) + const displayAmount = this.getDisplayAmount(paymentRequired); + + return getPaywallHtml({ + amount: displayAmount, + paymentRequirements: paymentRequired.accepts, + currentUrl: paymentRequired.resource?.url || finalConfig.currentUrl || "", + testnet: finalConfig.testnet ?? true, + cdpClientKey: finalConfig.cdpClientKey, + appName: finalConfig.appName, + appLogo: finalConfig.appLogo, + sessionTokenEndpoint: finalConfig.sessionTokenEndpoint, + }); + }, + }; + } + + /** + * Extract display amount from payment requirements. + * + * @param paymentRequired - The payment required object + * @returns The display amount in decimal format + */ + private getDisplayAmount(paymentRequired: PaymentRequired): number { + const accepts = paymentRequired.accepts; + if (accepts && accepts.length > 0) { + const firstReq = accepts[0]; + if ("amount" in firstReq && typeof firstReq.amount === "string") { + // V2 format + return parseFloat(firstReq.amount) / 1000000; // Assuming USDC with 6 decimals + } + if ("maxAmountRequired" in firstReq && typeof firstReq.maxAmountRequired === "string") { + // V1 format + return parseFloat(firstReq.maxAmountRequired) / 1000000; + } + } + return 0; + } +} + +/** + * Create a new paywall builder + * + * @returns A new PaywallBuilder instance + */ +export function createPaywall(): PaywallBuilder { + return new PaywallBuilder(); +} diff --git a/typescript/packages/http/paywall/src/evm/EvmPaywall.tsx b/typescript/packages/http/paywall/src/evm/EvmPaywall.tsx new file mode 100644 index 000000000..26dd4a447 --- /dev/null +++ b/typescript/packages/http/paywall/src/evm/EvmPaywall.tsx @@ -0,0 +1,305 @@ +import { FundButton, getOnrampBuyUrl } from "@coinbase/onchainkit/fund"; +import { Avatar, Name } from "@coinbase/onchainkit/identity"; +import { + ConnectWallet, + Wallet, + WalletDropdown, + WalletDropdownDisconnect, +} from "@coinbase/onchainkit/wallet"; +import { useCallback, useEffect, useMemo, useState } from "react"; +import { createPublicClient, formatUnits, http, publicActions } from "viem"; +import { base, baseSepolia } from "viem/chains"; +import { useAccount, useSwitchChain, useWalletClient } from "wagmi"; + +import { exact } from "x402/schemes"; +import { getUSDCBalance } from "x402/shared/evm"; +import type { PaymentRequirements } from "x402/types"; + +import { Spinner } from "./Spinner"; +import { useOnrampSessionToken } from "./useOnrampSessionToken"; +import { ensureValidAmount } from "../utils"; +import { getNetworkDisplayName, isTestnetNetwork } from "../paywallUtils"; + +type EvmPaywallProps = { + paymentRequirement: PaymentRequirements; + onSuccessfulResponse: (response: Response) => Promise; +}; + +/** + * Paywall experience for EVM networks. + * + * @param props - Component props. + * @param props.paymentRequirement - Payment requirement evaluated for the protected resource. + * @param props.onSuccessfulResponse - Callback fired once the 402 fetch succeeds. + * @returns JSX element. + */ +export function EvmPaywall({ paymentRequirement, onSuccessfulResponse }: EvmPaywallProps) { + const { address, isConnected, chainId: connectedChainId } = useAccount(); + const { switchChainAsync } = useSwitchChain(); + const { data: wagmiWalletClient } = useWalletClient(); + const { sessionToken } = useOnrampSessionToken(address); + + const [status, setStatus] = useState(""); + const [isCorrectChain, setIsCorrectChain] = useState(null); + const [isPaying, setIsPaying] = useState(false); + const [formattedUsdcBalance, setFormattedUsdcBalance] = useState(""); + const [hideBalance, setHideBalance] = useState(true); + + const x402 = window.x402; + const amount = + typeof x402.amount === "number" + ? x402.amount + : Number(paymentRequirement.maxAmountRequired ?? 0) / 1_000_000; + + const network = paymentRequirement.network; + const paymentChain = network === "base-sepolia" ? baseSepolia : base; + const chainId = paymentChain.id; + const chainName = getNetworkDisplayName(network); + const testnet = isTestnetNetwork(network); + const showOnramp = Boolean(!testnet && isConnected && x402.sessionTokenEndpoint); + + const publicClient = useMemo( + () => + createPublicClient({ + chain: paymentChain, + transport: http(), + }).extend(publicActions), + [paymentChain], + ); + + const checkUSDCBalance = useCallback(async () => { + if (!address) { + return; + } + const balance = await getUSDCBalance(publicClient, address); + const formattedBalance = formatUnits(balance, 6); + setFormattedUsdcBalance(formattedBalance); + }, [address, publicClient]); + + const handleSwitchChain = useCallback(async () => { + if (isCorrectChain) { + return; + } + + try { + setStatus(""); + await switchChainAsync({ chainId }); + await new Promise(resolve => setTimeout(resolve, 100)); + } catch (error) { + setStatus(error instanceof Error ? error.message : "Failed to switch network"); + } + }, [switchChainAsync, chainId, isCorrectChain]); + + useEffect(() => { + if (!address) { + return; + } + + void handleSwitchChain(); + void checkUSDCBalance(); + }, [address, handleSwitchChain, checkUSDCBalance]); + + useEffect(() => { + if (isConnected && chainId === connectedChainId) { + setIsCorrectChain(true); + setStatus(""); + } else if (isConnected && chainId !== connectedChainId) { + setIsCorrectChain(false); + setStatus(`On the wrong network. Please switch to ${chainName}.`); + } else { + setIsCorrectChain(null); + setStatus(""); + } + }, [chainId, connectedChainId, isConnected, chainName]); + + const onrampBuyUrl = useMemo(() => { + if (!sessionToken) { + return undefined; + } + return getOnrampBuyUrl({ + presetFiatAmount: 2, + fiatCurrency: "USD", + sessionToken, + }); + }, [sessionToken]); + + const handlePayment = useCallback(async () => { + if (!address || !x402) { + return; + } + + await handleSwitchChain(); + + if (!wagmiWalletClient) { + setStatus("Wallet client not available. Please reconnect your wallet."); + return; + } + const walletClient = wagmiWalletClient.extend(publicActions); + + setIsPaying(true); + + try { + setStatus("Checking USDC balance..."); + const balance = await getUSDCBalance(publicClient, address); + + if (balance === 0n) { + throw new Error(`Insufficient balance. Make sure you have USDC on ${chainName}`); + } + + setStatus("Creating payment signature..."); + const version = 1; // EvmPaywall uses v1 protocol + const validPaymentRequirements = ensureValidAmount(version, paymentRequirement); + const initialPayment = await exact.evm.createPayment( + walletClient, + version, + validPaymentRequirements, + ); + + const paymentHeader: string = exact.evm.encodePayment(initialPayment); + + setStatus("Requesting content with payment..."); + const response = await fetch(x402.currentUrl, { + headers: { + "X-PAYMENT": paymentHeader, + "Access-Control-Expose-Headers": "X-PAYMENT-RESPONSE", + }, + }); + + if (response.ok) { + await onSuccessfulResponse(response); + } else if (response.status === 402) { + const errorData = await response.json().catch(() => ({})); + if (errorData && typeof errorData.x402Version === "number") { + const retryPayment = await exact.evm.createPayment( + walletClient, + errorData.x402Version, + validPaymentRequirements, + ); + + retryPayment.x402Version = errorData.x402Version; + const retryHeader = exact.evm.encodePayment(retryPayment); + const retryResponse = await fetch(x402.currentUrl, { + headers: { + "X-PAYMENT": retryHeader, + "Access-Control-Expose-Headers": "X-PAYMENT-RESPONSE", + }, + }); + if (retryResponse.ok) { + await onSuccessfulResponse(retryResponse); + return; + } else { + throw new Error(`Payment retry failed: ${retryResponse.statusText}`); + } + } else { + throw new Error(`Payment failed: ${response.statusText}`); + } + } else { + throw new Error(`Request failed: ${response.status} ${response.statusText}`); + } + } catch (error) { + setStatus(error instanceof Error ? error.message : "Payment failed"); + } finally { + setIsPaying(false); + } + }, [ + address, + x402, + paymentRequirement, + handleSwitchChain, + wagmiWalletClient, + publicClient, + chainName, + onSuccessfulResponse, + ]); + + if (!x402) { + return null; + } + + return ( +
+
+

Payment Required

+

+ {paymentRequirement.description && `${paymentRequirement.description}.`} To access this + content, please pay ${amount} {chainName} USDC. +

+ {testnet && ( +

+ Need {chainName} USDC?{" "} + + Get some here. + +

+ )} +
+ +
+ + + + + + + + + + {isConnected && ( +
+
+
+ Wallet: + + {address ? `${address.slice(0, 6)}...${address.slice(-4)}` : "Loading..."} + +
+
+ Available balance: + + + +
+
+ Amount: + ${amount} USDC +
+
+ Network: + {chainName} +
+
+ + {isCorrectChain ? ( +
+ {showOnramp && ( + + )} + +
+ ) : ( + + )} +
+ )} + {status &&
{status}
} +
+
+ ); +} diff --git a/typescript/packages/x402/src/paywall/src/Spinner.tsx b/typescript/packages/http/paywall/src/evm/Spinner.tsx similarity index 100% rename from typescript/packages/x402/src/paywall/src/Spinner.tsx rename to typescript/packages/http/paywall/src/evm/Spinner.tsx diff --git a/typescript/packages/http/paywall/src/evm/build.ts b/typescript/packages/http/paywall/src/evm/build.ts new file mode 100644 index 000000000..4cd474e48 --- /dev/null +++ b/typescript/packages/http/paywall/src/evm/build.ts @@ -0,0 +1,90 @@ +import esbuild from "esbuild"; +import { htmlPlugin } from "@craftamap/esbuild-plugin-html"; +import fs from "fs"; +import path from "path"; +import { getBaseTemplate } from "../baseTemplate"; + +// EVM-specific build - only bundles EVM dependencies +const DIST_DIR = "src/evm/dist"; +const OUTPUT_HTML = path.join(DIST_DIR, "evm-paywall.html"); +const OUTPUT_TS = path.join("src/evm/gen", "template.ts"); + +const options: esbuild.BuildOptions = { + entryPoints: ["src/evm/index.tsx", "src/styles.css"], + bundle: true, + metafile: true, + outdir: DIST_DIR, + treeShaking: true, + minify: true, + format: "iife", + sourcemap: false, + platform: "browser", + target: "es2020", + jsx: "transform", + define: { + "process.env.NODE_ENV": '"development"', + global: "globalThis", + Buffer: "globalThis.Buffer", + }, + mainFields: ["browser", "module", "main"], + conditions: ["browser"], + plugins: [ + htmlPlugin({ + files: [ + { + entryPoints: ["src/evm/index.tsx", "src/styles.css"], + filename: "evm-paywall.html", + title: "Payment Required", + scriptLoading: "module", + inline: { + css: true, + js: true, + }, + htmlTemplate: getBaseTemplate(), + }, + ], + }), + ], + inject: ["./src/buffer-polyfill.ts"], + external: ["crypto"], +}; + +/** + * Builds the EVM paywall HTML template with bundled JS and CSS. + */ +async function build() { + try { + if (!fs.existsSync(DIST_DIR)) { + fs.mkdirSync(DIST_DIR, { recursive: true }); + } + + const genDir = path.dirname(OUTPUT_TS); + if (!fs.existsSync(genDir)) { + fs.mkdirSync(genDir, { recursive: true }); + } + + await esbuild.build(options); + console.log("[EVM] Build completed successfully!"); + + if (fs.existsSync(OUTPUT_HTML)) { + const html = fs.readFileSync(OUTPUT_HTML, "utf8"); + + const tsContent = `// THIS FILE IS AUTO-GENERATED - DO NOT EDIT +/** + * The pre-built EVM paywall template with inlined CSS and JS + */ +export const EVM_PAYWALL_TEMPLATE = ${JSON.stringify(html)}; +`; + + fs.writeFileSync(OUTPUT_TS, tsContent); + console.log(`[EVM] Generated template.ts (${(html.length / 1024 / 1024).toFixed(2)} MB)`); + } else { + throw new Error(`EVM bundled HTML not found at ${OUTPUT_HTML}`); + } + } catch (error) { + console.error("[EVM] Build failed:", error); + process.exit(1); + } +} + +build(); diff --git a/typescript/packages/http/paywall/src/evm/gen/template.ts b/typescript/packages/http/paywall/src/evm/gen/template.ts new file mode 100644 index 000000000..1806156fe --- /dev/null +++ b/typescript/packages/http/paywall/src/evm/gen/template.ts @@ -0,0 +1,5 @@ +// THIS FILE IS AUTO-GENERATED - DO NOT EDIT +/** + * The pre-built EVM paywall template with inlined CSS and JS + */ +export const EVM_PAYWALL_TEMPLATE = "\n \n \n Payment Required\n \n
\n \n \n "; diff --git a/typescript/packages/http/paywall/src/evm/index.ts b/typescript/packages/http/paywall/src/evm/index.ts new file mode 100644 index 000000000..bcc16ba53 --- /dev/null +++ b/typescript/packages/http/paywall/src/evm/index.ts @@ -0,0 +1,71 @@ +import type { + PaywallNetworkHandler, + PaymentRequirements, + PaymentRequired, + PaywallConfig, +} from "../types"; +import { getEvmPaywallHtml } from "./paywall"; +import { EVM_NETWORKS, type EVMNetworkV1 } from "@x402/core/types"; + +/** + * EVM paywall handler that supports EVM-based networks + */ +export const evmPaywall: PaywallNetworkHandler = { + /** + * Check if this handler supports the given payment requirement + * + * @param x402Version - The x402 protocol version + * @param requirement - Payment requirement to check + * @returns True if this handler can process this requirement + */ + supports(x402Version: number, requirement: PaymentRequirements): boolean { + const network = requirement.network; + + if (x402Version === 2) { + // v2: CAIP-2 format (eip155:*) + return network.startsWith("eip155:"); + } + + if (x402Version === 1) { + // v1: legacy network names + return EVM_NETWORKS.includes(network as EVMNetworkV1); + } + + return false; + }, + + /** + * Generate EVM-specific paywall HTML + * + * @param requirement - The selected payment requirement + * @param paymentRequired - Full payment required response + * @param config - Paywall configuration + * @returns HTML string for the paywall page + */ + generateHtml( + requirement: PaymentRequirements, + paymentRequired: PaymentRequired, + config: PaywallConfig, + ): string { + // Calculate display amount + const amount = requirement.amount + ? parseFloat(requirement.amount) / 1000000 + : requirement.maxAmountRequired + ? parseFloat(requirement.maxAmountRequired) / 1000000 + : 0; + + return getEvmPaywallHtml({ + amount, + paymentRequirements: [requirement], + currentUrl: paymentRequired.resource?.url || config.currentUrl || "", + testnet: config.testnet ?? true, + cdpClientKey: config.cdpClientKey, + appName: config.appName, + appLogo: config.appLogo, + sessionTokenEndpoint: config.sessionTokenEndpoint, + }); + }, +}; + +// Also export components for custom UI builders +export { EvmPaywall } from "./EvmPaywall"; diff --git a/typescript/packages/http/paywall/src/evm/index.tsx b/typescript/packages/http/paywall/src/evm/index.tsx new file mode 100644 index 000000000..357b43556 --- /dev/null +++ b/typescript/packages/http/paywall/src/evm/index.tsx @@ -0,0 +1,55 @@ +import React from "react"; +import { createRoot } from "react-dom/client"; +import { OnchainKitProvider } from "@coinbase/onchainkit"; +import { base, baseSepolia } from "viem/chains"; +import { EvmPaywall } from "./EvmPaywall"; + +// EVM-specific paywall entry point +window.addEventListener("load", () => { + const rootElement = document.getElementById("root"); + if (!rootElement) { + console.error("Root element not found"); + return; + } + + const x402 = window.x402; + const chain = x402.paymentRequirements[0]?.network === "base-sepolia" ? baseSepolia : base; + + const root = createRoot(rootElement); + root.render( + + { + const contentType = response.headers.get("content-type"); + if (contentType && contentType.includes("text/html")) { + document.documentElement.innerHTML = await response.text(); + } else { + const blob = await response.blob(); + const url = window.URL.createObjectURL(blob); + window.location.href = url; + } + }} + /> + , + ); +}); diff --git a/typescript/packages/http/paywall/src/evm/paywall.ts b/typescript/packages/http/paywall/src/evm/paywall.ts new file mode 100644 index 000000000..3a6fc86f5 --- /dev/null +++ b/typescript/packages/http/paywall/src/evm/paywall.ts @@ -0,0 +1,111 @@ +import type { PaymentRequirements } from "../types"; + +/** + * Escapes a string for safe injection into JavaScript string literals + * + * @param str - The string to escape + * @returns The escaped string + */ +function escapeString(str: string): string { + return str + .replace(/\\/g, "\\\\") + .replace(/"/g, '\\"') + .replace(/'/g, "\\'") + .replace(/\n/g, "\\n") + .replace(/\r/g, "\\r") + .replace(/\t/g, "\\t"); +} + +/** + * Gets the EVM chain config + * + * @returns The EVM chain config + */ +function getChainConfig() { + return { + base: { + usdcAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + usdcName: "USDC", + }, + "base-sepolia": { + usdcAddress: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", + usdcName: "USDC", + }, + }; +} + +interface EvmPaywallOptions { + amount: number; + paymentRequirements: PaymentRequirements[]; + currentUrl: string; + testnet: boolean; + cdpClientKey?: string; + appName?: string; + appLogo?: string; + sessionTokenEndpoint?: string; +} + +/** + * Generates EVM-specific paywall HTML + * + * @param options - The options for generating the paywall + * @param options.amount - The amount to be paid in USD + * @param options.paymentRequirements - The payment requirements for the content + * @param options.currentUrl - The URL of the content being accessed + * @param options.testnet - Whether to use testnet or mainnet + * @param options.cdpClientKey - CDP client API key for OnchainKit + * @param options.appName - The name of the application to display in the wallet connection modal + * @param options.appLogo - The logo of the application to display in the wallet connection modal + * @param options.sessionTokenEndpoint - The API endpoint for generating session tokens for Onramp authentication + * @returns HTML string for the paywall page + */ +export function getEvmPaywallHtml(options: EvmPaywallOptions): string { + let EVM_PAYWALL_TEMPLATE: string; + + try { + // Will be generated by build script + // eslint-disable-next-line @typescript-eslint/no-require-imports + const template = require("./gen/template"); + EVM_PAYWALL_TEMPLATE = template.EVM_PAYWALL_TEMPLATE; + } catch { + // Template not built yet, return placeholder + return `

EVM Paywall (run pnpm build:paywall to generate full template)

`; + } + + const { + amount, + testnet, + paymentRequirements, + currentUrl, + cdpClientKey, + appName, + appLogo, + sessionTokenEndpoint, + } = options; + + const logOnTestnet = testnet + ? "console.log('EVM Payment requirements initialized:', window.x402);" + : ""; + + const config = getChainConfig(); + + const configScript = ` + `; + + return EVM_PAYWALL_TEMPLATE.replace("", `${configScript}\n`); +} diff --git a/typescript/packages/http/paywall/src/evm/useOnrampSessionToken.ts b/typescript/packages/http/paywall/src/evm/useOnrampSessionToken.ts new file mode 100644 index 000000000..3189d0ebc --- /dev/null +++ b/typescript/packages/http/paywall/src/evm/useOnrampSessionToken.ts @@ -0,0 +1,52 @@ +import { useCallback, useState, useEffect } from "react"; +import { generateOnrampSessionToken } from "../utils"; + +type UseOnrampSessionTokenProps = { + sessionToken: string | undefined; +}; + +const TOKEN_EXPIRY_TIME = 5 * 60 * 1000; + +/** + * Custom hook to manage onramp session token state and lifecycle + * + * @param address - The user's wallet address + * @returns Object containing session token state + */ +export function useOnrampSessionToken(address: string | undefined): UseOnrampSessionTokenProps { + const [sessionToken, setSessionToken] = useState(); + const [tokenTimestamp, setTokenTimestamp] = useState(null); + + const isTokenExpired = useCallback(() => { + if (!tokenTimestamp) return true; + return Date.now() - tokenTimestamp > TOKEN_EXPIRY_TIME; + }, [tokenTimestamp]); + + const generateToken = useCallback(async () => { + if (!address) { + return; + } + + // Token expires after 5 minutes, but once authorized it can be used + // indefinitely with the same sessionId + if (!sessionToken || isTokenExpired()) { + const token = await generateOnrampSessionToken(address); + setSessionToken(token); + setTokenTimestamp(Date.now()); + } + }, [address, sessionToken, isTokenExpired]); + + // Generate token when address changes or component mounts + useEffect(() => { + if (address) { + generateToken(); + } else { + setSessionToken(undefined); + setTokenTimestamp(null); + } + }, [address, generateToken]); + + return { + sessionToken, + }; +} diff --git a/typescript/packages/http/paywall/src/gen/template.ts b/typescript/packages/http/paywall/src/gen/template.ts new file mode 100644 index 000000000..370a79cb4 --- /dev/null +++ b/typescript/packages/http/paywall/src/gen/template.ts @@ -0,0 +1,5 @@ +// THIS FILE IS AUTO-GENERATED - DO NOT EDIT +/** + * The pre-built, self-contained paywall template with inlined CSS and JS + */ +export const PAYWALL_TEMPLATE = "\n \n \n Payment Required\n \n
\n \n \n "; diff --git a/typescript/packages/http/paywall/src/index.test.ts b/typescript/packages/http/paywall/src/index.test.ts new file mode 100644 index 000000000..00ba68187 --- /dev/null +++ b/typescript/packages/http/paywall/src/index.test.ts @@ -0,0 +1,12 @@ +import { describe, it, expect } from "vitest"; + +describe("@x402/paywall", () => { + it("should be defined", () => { + expect(true).toBe(true); + }); + + // TODO: Add actual tests for paywall functionality + it.todo("should handle payment required responses"); + it.todo("should render paywall UI"); + it.todo("should process payments"); +}); diff --git a/typescript/packages/http/paywall/src/index.ts b/typescript/packages/http/paywall/src/index.ts new file mode 100644 index 000000000..ddeb99209 --- /dev/null +++ b/typescript/packages/http/paywall/src/index.ts @@ -0,0 +1,21 @@ +/** + * @module @x402/paywall - x402 Payment Protocol Paywall Extension + * This module provides paywall functionality for the x402 payment protocol. + */ + +// Legacy function export (v1 compatibility) +export { getPaywallHtml } from "./paywall"; + +// Builder pattern exports (v2) +export { createPaywall, PaywallBuilder } from "./builder"; +export type { + PaywallProvider, + PaywallConfig, + PaymentRequired, + PaywallNetworkHandler, + PaymentRequirements, +} from "./types"; + +// Re-export network handlers for convenience +export { evmPaywall } from "./evm"; +export { svmPaywall } from "./svm"; diff --git a/typescript/packages/http/paywall/src/index.tsx b/typescript/packages/http/paywall/src/index.tsx new file mode 100644 index 000000000..3a91b729c --- /dev/null +++ b/typescript/packages/http/paywall/src/index.tsx @@ -0,0 +1,20 @@ +import React from "react"; +import { createRoot } from "react-dom/client"; +import { Providers } from "./Providers"; +import { PaywallApp } from "./PaywallApp"; + +// Initialize the app when the window loads +window.addEventListener("load", () => { + const rootElement = document.getElementById("root"); + if (!rootElement) { + console.error("Root element not found"); + return; + } + + const root = createRoot(rootElement); + root.render( + + + , + ); +}); diff --git a/typescript/packages/http/paywall/src/network-handlers.test.ts b/typescript/packages/http/paywall/src/network-handlers.test.ts new file mode 100644 index 000000000..a24e49420 --- /dev/null +++ b/typescript/packages/http/paywall/src/network-handlers.test.ts @@ -0,0 +1,92 @@ +import { describe, expect, it } from "vitest"; +import { evmPaywall } from "./evm"; +import { svmPaywall } from "./svm"; +import type { PaymentRequired, PaymentRequirements } from "./types"; + +const evmRequirement: PaymentRequirements = { + scheme: "exact", + network: "eip155:8453", + asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + amount: "100000", + payTo: "0x209693Bc6afc0C5328bA36FaF04C514EF312287C", + maxTimeoutSeconds: 60, +}; + +const svmRequirement: PaymentRequirements = { + scheme: "exact", + network: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", + asset: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + amount: "100000", + payTo: "2wKupLR9q6wXYppw8Gr2NvWxKBUqm4PPJKkQfoxHEBg4", + maxTimeoutSeconds: 60, +}; + +const mockPaymentRequired: PaymentRequired = { + x402Version: 2, + resource: { + url: "https://example.com/api/data", + description: "Test", + mimeType: "application/json", + }, + accepts: [evmRequirement], +}; + +describe("Network Handlers", () => { + describe("evmPaywall", () => { + it("supports v2 CAIP-2 EVM networks", () => { + expect(evmPaywall.supports(2, { ...evmRequirement, network: "eip155:8453" })).toBe(true); + expect(evmPaywall.supports(2, { ...evmRequirement, network: "eip155:84532" })).toBe(true); + expect(evmPaywall.supports(2, { ...evmRequirement, network: "eip155:1" })).toBe(true); + }); + + it("supports v1 legacy EVM networks", () => { + expect(evmPaywall.supports(1, { ...evmRequirement, network: "base" })).toBe(true); + expect(evmPaywall.supports(1, { ...evmRequirement, network: "base-sepolia" })).toBe(true); + expect(evmPaywall.supports(1, { ...evmRequirement, network: "polygon" })).toBe(true); + }); + + it("rejects non-EVM networks", () => { + expect(evmPaywall.supports(2, { ...evmRequirement, network: "solana:5eykt" })).toBe(false); + expect(evmPaywall.supports(1, { ...evmRequirement, network: "solana-devnet" })).toBe(false); + }); + + it("generates HTML for EVM networks", () => { + const html = evmPaywall.generateHtml(evmRequirement, mockPaymentRequired, { + appName: "Test App", + testnet: true, + }); + + expect(html).toContain(""); + // Check for either full template or placeholder (templates may not be built in test env) + expect(html).toMatch(/Test App|EVM Paywall/); + }); + }); + + describe("svmPaywall", () => { + it("supports v2 CAIP-2 Solana networks", () => { + expect(svmPaywall.supports(2, { ...svmRequirement, network: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp" })).toBe(true); + expect(svmPaywall.supports(2, { ...svmRequirement, network: "solana:devnet" })).toBe(true); + }); + + it("supports v1 legacy Solana networks", () => { + expect(svmPaywall.supports(1, { ...svmRequirement, network: "solana" })).toBe(true); + expect(svmPaywall.supports(1, { ...svmRequirement, network: "solana-devnet" })).toBe(true); + }); + + it("rejects non-Solana networks", () => { + expect(svmPaywall.supports(2, { ...svmRequirement, network: "eip155:8453" })).toBe(false); + expect(svmPaywall.supports(1, { ...svmRequirement, network: "base" })).toBe(false); + }); + + it("generates HTML for Solana networks", () => { + const html = svmPaywall.generateHtml(svmRequirement, mockPaymentRequired, { + appName: "Solana Test", + testnet: true, + }); + + expect(html).toContain(""); + // Check for either full template or placeholder (templates may not be built in test env) + expect(html).toMatch(/Solana Test|SVM Paywall/); + }); + }); +}); diff --git a/typescript/packages/http/paywall/src/paywall.ts b/typescript/packages/http/paywall/src/paywall.ts new file mode 100644 index 000000000..932d8db59 --- /dev/null +++ b/typescript/packages/http/paywall/src/paywall.ts @@ -0,0 +1,104 @@ +import { PAYWALL_TEMPLATE } from "./gen/template"; + +import type { PaymentRequirements } from "./types"; + +interface PaywallOptions { + amount: number; + paymentRequirements: PaymentRequirements[]; + currentUrl: string; + testnet: boolean; + cdpClientKey?: string; + appName?: string; + appLogo?: string; + sessionTokenEndpoint?: string; +} + +/** + * Escapes a string for safe injection into JavaScript string literals + * + * @param str - The string to escape + * @returns The escaped string + */ +function escapeString(str: string): string { + return str + .replace(/\\/g, "\\\\") + .replace(/"/g, '\\"') + .replace(/'/g, "\\'") + .replace(/\n/g, "\\n") + .replace(/\r/g, "\\r") + .replace(/\t/g, "\\t"); +} + +/** + * Gets the EVM chain config from window.x402.config + * This is a placeholder that will be populated at runtime + * + * @returns The chain config + */ +function getChainConfig() { + // This config will come from the legacy x402 package + // For now, return a basic structure + return { + base: { + usdcAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + usdcName: "USDC", + }, + "base-sepolia": { + usdcAddress: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", + usdcName: "USDC", + }, + }; +} + +/** + * Generates an HTML paywall page that allows users to pay for content access + * + * @param options - The options for generating the paywall + * @param options.amount - The amount to be paid in USD + * @param options.paymentRequirements - The payment requirements for the content + * @param options.currentUrl - The URL of the content being accessed + * @param options.testnet - Whether to use testnet or mainnet + * @param options.cdpClientKey - CDP client API key for OnchainKit + * @param options.appName - The name of the application to display in the wallet connection modal + * @param options.appLogo - The logo of the application to display in the wallet connection modal + * @param options.sessionTokenEndpoint - The API endpoint for generating session tokens for Onramp authentication + * @returns An HTML string containing the paywall page + */ +export function getPaywallHtml({ + amount, + testnet, + paymentRequirements, + currentUrl, + cdpClientKey, + appName, + appLogo, + sessionTokenEndpoint, +}: PaywallOptions): string { + const logOnTestnet = testnet + ? "console.log('Payment requirements initialized:', window.x402);" + : ""; + + const config = getChainConfig(); + + // Create the configuration script to inject with proper escaping + const configScript = ` + `; + + // Inject the configuration script into the head + return PAYWALL_TEMPLATE.replace("", `${configScript}\n`); +} diff --git a/typescript/packages/http/paywall/src/paywallUtils.test.ts b/typescript/packages/http/paywall/src/paywallUtils.test.ts new file mode 100644 index 000000000..19467e562 --- /dev/null +++ b/typescript/packages/http/paywall/src/paywallUtils.test.ts @@ -0,0 +1,163 @@ +import { describe, expect, it } from "vitest"; +import type { PaymentRequirements } from "x402/types"; +import { + choosePaymentRequirement, + getNetworkDisplayName, + isEvmNetwork, + isSvmNetwork, + normalizePaymentRequirements, + isTestnetNetwork, +} from "./paywallUtils"; + +const baseRequirement: PaymentRequirements = { + scheme: "exact", + network: "base", + maxAmountRequired: "1000", + resource: "https://example.com/protected", + description: "Base resource", + mimeType: "application/json", + payTo: "0x0000000000000000000000000000000000000001", + maxTimeoutSeconds: 60, + asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + extra: { + feePayer: "0x0000000000000000000000000000000000000003", + }, +}; + +const baseSepoliaRequirement: PaymentRequirements = { + ...baseRequirement, + network: "base-sepolia", + description: "Base Sepolia resource", + asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", +}; + +const solanaRequirement: PaymentRequirements = { + scheme: "exact", + network: "solana", + maxAmountRequired: "1000", + resource: "https://example.com/solana", + description: "Solana resource", + mimeType: "application/json", + payTo: "2Zt8RZ8kW1nWcJ6YyqHq9kTjY8QpM2R2t1xXUQ1e1VQa", + maxTimeoutSeconds: 60, + asset: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + extra: { + feePayer: "3d9yxXikBVYjgvPbJF4dPSt31Z87Nb5fV9jXYzQ3QAtc", + }, +}; + +describe("paywallUtils", () => { + describe("normalizePaymentRequirements", () => { + it("normalizes single payment requirement into an array", () => { + const normalized = normalizePaymentRequirements(baseRequirement); + expect(normalized).toHaveLength(1); + expect(normalized[0]).toBe(baseRequirement); + }); + + it("returns array as-is when already an array", () => { + const requirements = [baseRequirement, solanaRequirement]; + const normalized = normalizePaymentRequirements(requirements); + expect(normalized).toBe(requirements); + expect(normalized).toHaveLength(2); + }); + }); + + describe("choosePaymentRequirement", () => { + it("selects base payment on mainnet preference", () => { + const selected = choosePaymentRequirement([solanaRequirement, baseRequirement], false); + expect(selected.network).toBe("base"); + }); + + it("selects base sepolia payment on testnet preference", () => { + const selected = choosePaymentRequirement([solanaRequirement, baseSepoliaRequirement], true); + expect(selected.network).toBe("base-sepolia"); + }); + + it("falls back to solana when no evm networks exist", () => { + const selected = choosePaymentRequirement([solanaRequirement], false); + expect(selected.network).toBe("solana"); + }); + + it("returns first requirement when no preferred networks match", () => { + const customRequirement = { ...baseRequirement, network: "polygon" }; + const selected = choosePaymentRequirement([customRequirement], true); + expect(selected).toBe(customRequirement); + }); + }); + + describe("getNetworkDisplayName", () => { + it("returns display names for v1 legacy networks", () => { + expect(getNetworkDisplayName("base")).toBe("Base"); + expect(getNetworkDisplayName("base-sepolia")).toBe("Base Sepolia"); + expect(getNetworkDisplayName("solana")).toBe("Solana"); + expect(getNetworkDisplayName("solana-devnet")).toBe("Solana Devnet"); + }); + + it("returns display names for v2 CAIP-2 EVM networks", () => { + expect(getNetworkDisplayName("eip155:8453")).toBe("Base"); + expect(getNetworkDisplayName("eip155:84532")).toBe("Base Sepolia"); + expect(getNetworkDisplayName("eip155:1")).toBe("EVM Chain 1"); + }); + + it("returns display names for v2 CAIP-2 Solana networks", () => { + expect(getNetworkDisplayName("solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp")).toContain("Solana"); + }); + + it("returns network as-is for unknown networks", () => { + expect(getNetworkDisplayName("unknown")).toBe("unknown"); + }); + }); + + describe("isEvmNetwork", () => { + it("identifies v1 legacy EVM networks", () => { + expect(isEvmNetwork("base")).toBe(true); + expect(isEvmNetwork("base-sepolia")).toBe(true); + expect(isEvmNetwork("polygon")).toBe(true); + }); + + it("identifies v2 CAIP-2 EVM networks", () => { + expect(isEvmNetwork("eip155:8453")).toBe(true); + expect(isEvmNetwork("eip155:84532")).toBe(true); + expect(isEvmNetwork("eip155:1")).toBe(true); + }); + + it("rejects non-EVM networks", () => { + expect(isEvmNetwork("solana")).toBe(false); + expect(isEvmNetwork("solana-devnet")).toBe(false); + expect(isEvmNetwork("solana:5eykt")).toBe(false); + }); + }); + + describe("isSvmNetwork", () => { + it("identifies v1 legacy Solana networks", () => { + expect(isSvmNetwork("solana")).toBe(true); + expect(isSvmNetwork("solana-devnet")).toBe(true); + }); + + it("identifies v2 CAIP-2 Solana networks", () => { + expect(isSvmNetwork("solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp")).toBe(true); + expect(isSvmNetwork("solana:devnet")).toBe(true); + }); + + it("rejects non-Solana networks", () => { + expect(isSvmNetwork("base")).toBe(false); + expect(isSvmNetwork("eip155:8453")).toBe(false); + }); + }); + + describe("isTestnetNetwork", () => { + it("identifies EVM testnets", () => { + expect(isTestnetNetwork("base-sepolia")).toBe(true); + expect(isTestnetNetwork("polygon-amoy")).toBe(true); + }); + + it("identifies Solana testnets", () => { + expect(isTestnetNetwork("solana-devnet")).toBe(true); + }); + + it("rejects mainnets", () => { + expect(isTestnetNetwork("base")).toBe(false); + expect(isTestnetNetwork("solana")).toBe(false); + }); + }); +}); diff --git a/typescript/packages/http/paywall/src/paywallUtils.ts b/typescript/packages/http/paywall/src/paywallUtils.ts new file mode 100644 index 000000000..90023669c --- /dev/null +++ b/typescript/packages/http/paywall/src/paywallUtils.ts @@ -0,0 +1,145 @@ +import type { PaymentRequirements } from "x402/types"; + +// Define supported networks inline to avoid circular dependencies +const EVM_NETWORKS = [ + "base", + "base-sepolia", + "abstract", + "abstract-testnet", + "avalanche", + "avalanche-fuji", + "iotex", + "sei", + "sei-testnet", + "polygon", + "polygon-amoy", + "peaq", +]; +const SVM_NETWORKS = ["solana", "solana-devnet"]; +const EVM_TESTNETS = new Set([ + "base-sepolia", + "abstract-testnet", + "avalanche-fuji", + "sei-testnet", + "polygon-amoy", +]); +const SVM_TESTNETS = new Set(["solana-devnet"]); + +/** + * Normalizes the payment requirements into an array. + * + * @param paymentRequirements - A single requirement or a list of requirements. + * @returns An array of payment requirements. + */ +export function normalizePaymentRequirements( + paymentRequirements: PaymentRequirements | PaymentRequirements[], +): PaymentRequirements[] { + if (Array.isArray(paymentRequirements)) { + return paymentRequirements; + } + return [paymentRequirements]; +} + +/** + * Returns the preferred networks to attempt first when selecting a payment requirement. + * + * @param testnet - Whether the paywall is operating in testnet mode. + * @returns Ordered list of preferred networks. + */ +export function getPreferredNetworks(testnet: boolean): string[] { + if (testnet) { + return ["base-sepolia", "solana-devnet"]; + } + return ["base", "solana"]; +} + +/** + * Selects the most appropriate payment requirement for the user. + * + * @param paymentRequirements - All available payment requirements. + * @param testnet - Whether the paywall is operating in testnet mode. + * @returns The selected payment requirement. + */ +export function choosePaymentRequirement( + paymentRequirements: PaymentRequirements | PaymentRequirements[], + testnet: boolean, +): PaymentRequirements { + const normalized = normalizePaymentRequirements(paymentRequirements); + const preferredNetworks = getPreferredNetworks(testnet); + + // Try to find a requirement matching preferred networks + for (const preferredNetwork of preferredNetworks) { + const match = normalized.find(req => req.network === preferredNetwork); + if (match) { + return match; + } + } + + // Fall back to first requirement + return normalized[0]; +} + +/** + * Determines if the provided network is an EVM network. + * + * @param network - The network to check. + * @returns True if the network is EVM based. + */ +export function isEvmNetwork(network: string): boolean { + // Check both v1 legacy format and v2 CAIP-2 format (eip155:*) + return EVM_NETWORKS.includes(network) || network.startsWith("eip155:"); +} + +/** + * Determines if the provided network is an SVM network. + * + * @param network - The network to check. + * @returns True if the network is SVM based. + */ +export function isSvmNetwork(network: string): boolean { + // Check both v1 legacy format and v2 CAIP-2 format (solana:*) + return SVM_NETWORKS.includes(network) || network.startsWith("solana:"); +} + +/** + * Provides a human-readable display name for a network. + * + * @param network - The network identifier. + * @returns A display name suitable for UI use. + */ +export function getNetworkDisplayName(network: string): string { + // Handle CAIP-2 format + if (network.startsWith("eip155:")) { + const chainId = network.split(":")[1]; + if (chainId === "8453") return "Base"; + if (chainId === "84532") return "Base Sepolia"; + return `EVM Chain ${chainId}`; + } + if (network.startsWith("solana:")) { + return network.includes("devnet") ? "Solana Devnet" : "Solana"; + } + + // Handle v1 legacy format + switch (network) { + case "base": + return "Base"; + case "base-sepolia": + return "Base Sepolia"; + case "solana": + return "Solana"; + case "solana-devnet": + return "Solana Devnet"; + default: + return network; + } +} + +/** + * Indicates whether the provided network is a testnet. + * + * @param network - The network to evaluate. + * @returns True if the network is a recognized testnet. + */ +export function isTestnetNetwork(network: string): boolean { + return EVM_TESTNETS.has(network) || SVM_TESTNETS.has(network); +} diff --git a/typescript/packages/http/paywall/src/styles.css b/typescript/packages/http/paywall/src/styles.css new file mode 100644 index 000000000..c45d40fef --- /dev/null +++ b/typescript/packages/http/paywall/src/styles.css @@ -0,0 +1,248 @@ +@import "@coinbase/onchainkit/styles.css"; +/* Reset */ +*, +*::before, +*::after { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +body { + line-height: 1.5; + -webkit-font-smoothing: antialiased; +} + +img, +picture, +video, +canvas, +svg { + display: block; + max-width: 100%; +} + +input, +button, +textarea, +select { + font: inherit; +} + +p, +h1, +h2, +h3, +h4, +h5, +h6 { + overflow-wrap: break-word; +} + +/* Custom Styles */ +:root { + --background-color: #f9fafb; + --container-background-color: white; + --text-color: #111827; + --secondary-text-color: #4b5563; + --details-background-color: #f9fafb; + --details-background-color-hover: #f3f4f6; + --button-primary-color: #2563eb; + --button-primary-hover-color: #1d4ed8; + --button-secondary-color: #eef0f3; + --button-secondary-hover-color: #e9ebee; + --button-positive-color: #059669; + --button-positive-hover-color: #047857; + --button-error-color: #ef4444; + --button-error-hover-color: #dc2626; +} + +.ock-font-family { + font-family: "Inter", system-ui, -apple-system, sans-serif; +} + +.ock-bg-secondary, .ock-bg-default { + background-color: var(--details-background-color); + transition: background-color 150ms; +} + +.ock-bg-secondary:hover { + background-color: var(--details-background-color-hover); +} + +.opacity-80 { + opacity: 0.8; +} + +[data-testid="ockWalletDropdown"] { + z-index: 10; +} + +body { + min-height: 100vh; + background-color: var(--background-color); + font-family: + "Inter", + system-ui, + -apple-system, + sans-serif; +} + +.container { + max-width: 32rem; + margin: 4rem auto; + padding: 1.5rem; + background-color: var(--container-background-color); + border-radius: 0.75rem; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + box-shadow: + 0 4px 6px -1px rgba(0, 0, 0, 0.1), + 0 2px 4px -1px rgba(0, 0, 0, 0.06); +} + +.header { + display: flex; + flex-direction: column; + gap: 1rem; +} + +.title { + font-size: 1.5rem; + font-weight: 700; + color: var(--text-color); + margin-bottom: 0.5rem; +} + +.subtitle { + color: var(--secondary-text-color); +} + +.instructions { + font-size: 0.9rem; + color: var(--secondary-text-color); + font-style: italic; +} + +.content { + display: flex; + flex-direction: column; + gap: 1rem; +} + +.input { + width: 100%; + padding: 0.75rem 1rem; + border-radius: 0.5rem; + border: 1px solid #d1d5db; + background-color: white; + transition: border-color 150ms, box-shadow 150ms; +} + +.input:focus { + outline: none; + border-color: var(--button-primary-color); + box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2); +} + +.button { + width: 100%; + padding: 0.75rem 1rem; + border-radius: 0.5rem; + font-weight: 600; + border: none; + cursor: pointer; + transition: background-color 150ms; +} + +.button-primary { + background-color: var(--button-primary-color); + color: white; +} + +.button-primary:hover { + background-color: var(--button-primary-hover-color); +} + +.button-secondary { + background-color: var(--button-secondary-color); + color: var(--text-color); +} + +.button-secondary:hover { + background-color: var(--button-secondary-hover-color); +} + +.button-positive { + background-color: var(--button-positive-color); + color: white; +} + +.button-positive:hover { + background-color: var(--button-positive-hover-color); +} + +.button-error { + background-color: var(--button-error-color); + color: white; +} + +.button-error:hover { + background-color: var(--button-error-hover-color); +} + +.payment-details { + padding: 1rem; + margin-bottom: 1rem; + background-color: var(--details-background-color); + border-radius: 0.5rem; +} + +.payment-row { + display: flex; + justify-content: space-between; + font-size: 0.875rem; + margin-bottom: 0.5rem; +} + +.payment-row:last-child { + margin-bottom: 0; +} + +.payment-label { + color: var(--text-color); +} + +.payment-value { + font-weight: 500; +} + +.hidden { + display: none; +} + +.status { + text-align: center; + font-size: 0.875rem; +} + +.cta-container { + display: flex; + flex-basis: 50%; + flex-direction: row; + gap: 0.5rem; +} + +.balance-button { + background-color: transparent; + border: none; + cursor: pointer; + min-height: 1rem; + min-width: 150px; + display: flex; + justify-content: flex-end; + align-items: center; +} + diff --git a/typescript/packages/http/paywall/src/svm/SolanaPaywall.tsx b/typescript/packages/http/paywall/src/svm/SolanaPaywall.tsx new file mode 100644 index 000000000..7a0cb5254 --- /dev/null +++ b/typescript/packages/http/paywall/src/svm/SolanaPaywall.tsx @@ -0,0 +1,347 @@ +import { useCallback, useEffect, useRef, useState } from "react"; +import type { WalletAccount } from "@wallet-standard/base"; +import type { WalletWithSolanaFeatures } from "@solana/wallet-standard-features"; + +import { exact } from "x402/schemes"; +import type { PaymentRequirements } from "x402/types"; + +import { Spinner } from "./Spinner"; +import { ensureValidAmount } from "../utils"; +import { getNetworkDisplayName } from "../paywallUtils"; +import { getStandardConnectFeature, getStandardDisconnectFeature } from "./solana/features"; +import { useSolanaBalance } from "./solana/useSolanaBalance"; +import { useSolanaSigner } from "./solana/useSolanaSigner"; +import { useSolanaWalletEvents } from "./solana/useSolanaWalletEvents"; +import { useSolanaWalletOptions } from "./solana/useSolanaWalletOptions"; +import { useSilentWalletConnection } from "./solana/useSilentWalletConnection"; +import type { WalletOption } from "./solana/types"; + +type SolanaPaywallProps = { + paymentRequirement: PaymentRequirements; + onSuccessfulResponse: (response: Response) => Promise; +}; + +/** + * Paywall experience for Solana networks. + * + * @param props - Component props. + * @param props.paymentRequirement - Payment requirement enforced for Solana requests. + * @param props.onSuccessfulResponse - Callback invoked on successful 402 response. + * @returns JSX element. + */ +export function SolanaPaywall({ paymentRequirement, onSuccessfulResponse }: SolanaPaywallProps) { + const [status, setStatus] = useState(""); + const [isPaying, setIsPaying] = useState(false); + const walletOptions = useSolanaWalletOptions(); + const [selectedWalletValue, setSelectedWalletValue] = useState(""); + const [activeWallet, setActiveWallet] = useState(null); + const [activeAccount, setActiveAccount] = useState(null); + const [hideBalance, setHideBalance] = useState(true); + const attemptedSilentConnectWalletsRef = useRef>(new Set()); + + const { usdcBalance, formattedBalance, isFetchingBalance, refreshBalance, resetBalance } = + useSolanaBalance({ + activeAccount, + paymentRequirement, + onStatus: setStatus, + }); + + const x402 = window.x402; + const amount = + typeof x402.amount === "number" + ? x402.amount + : Number(paymentRequirement.maxAmountRequired ?? 0) / 1_000_000; + + const network = paymentRequirement.network; + const chainName = getNetworkDisplayName(network); + const targetChain = + network === "solana" ? ("solana:mainnet" as const) : ("solana:devnet" as const); + + const walletSigner = useSolanaSigner({ + activeWallet, + activeAccount, + targetChain, + }); + + useEffect(() => { + if (!selectedWalletValue && walletOptions.length === 1) { + setSelectedWalletValue(walletOptions[0].value); + } + }, [walletOptions, selectedWalletValue]); + + useEffect(() => { + if (!activeWallet) { + return; + } + + if (!walletOptions.some(option => option.wallet === activeWallet)) { + setActiveWallet(null); + setActiveAccount(null); + setSelectedWalletValue(""); + resetBalance(); + } + }, [walletOptions, activeWallet, resetBalance]); + + useSilentWalletConnection({ + walletOptions, + activeWallet, + targetChain, + attemptedSilentConnectWalletsRef, + setSelectedWalletValue, + setActiveWallet, + setActiveAccount, + refreshBalance, + setStatus, + }); + + useSolanaWalletEvents({ + activeWallet, + targetChain, + chainName, + setActiveWallet, + setActiveAccount, + setSelectedWalletValue, + setStatus, + resetBalance, + refreshBalance, + }); + + const handleConnect = useCallback(async () => { + const wallet = walletOptions.find( + (option: WalletOption) => option.value === selectedWalletValue, + )?.wallet; + if (!wallet) { + setStatus("Select a Solana wallet to continue."); + return; + } + + const connectFeature = getStandardConnectFeature(wallet); + if (!connectFeature) { + setStatus("Selected wallet does not support standard connect."); + return; + } + + try { + setStatus("Connecting to wallet..."); + const { accounts } = await connectFeature.connect(); + if (!accounts?.length) { + throw new Error("Wallet did not provide any accounts."); + } + + const matchingAccount = + accounts.find((account: WalletAccount) => account.chains?.includes(targetChain)) ?? + accounts[0]; + + setActiveWallet(wallet); + setActiveAccount(matchingAccount); + setStatus(""); + await refreshBalance(matchingAccount); + } catch (error) { + console.error("Failed to connect wallet", error); + setStatus(error instanceof Error ? error.message : "Failed to connect wallet."); + } + }, [walletOptions, selectedWalletValue, targetChain, refreshBalance]); + + const handleDisconnect = useCallback(async () => { + const disconnectFeature = activeWallet && getStandardDisconnectFeature(activeWallet); + if (disconnectFeature) { + await disconnectFeature.disconnect().catch(console.error); + } + + setActiveWallet(null); + setActiveAccount(null); + resetBalance(); + setStatus(""); + }, [activeWallet, resetBalance]); + + const handlePayment = useCallback(async () => { + if (!x402) { + return; + } + + if (!walletSigner || !activeAccount) { + setStatus("Connect a Solana wallet before paying."); + return; + } + + setIsPaying(true); + + try { + if (usdcBalance === null || usdcBalance === 0n) { + setStatus("Checking USDC balance..."); + const latestBalance = await refreshBalance(); + if (!latestBalance || latestBalance === 0n) { + throw new Error(`Insufficient balance. Make sure you have USDC on ${chainName}.`); + } + } + + setStatus("Creating payment transaction..."); + const version = 1; // SolanaPaywall uses v1 protocol + const validPaymentRequirements = ensureValidAmount(version, paymentRequirement); + + const createHeader = async (version: number) => + exact.svm.createPaymentHeader(walletSigner, version, validPaymentRequirements); + + const paymentHeader = await createHeader(1); + + setStatus("Requesting content with payment..."); + const response = await fetch(x402.currentUrl, { + headers: { + "X-PAYMENT": paymentHeader, + "Access-Control-Expose-Headers": "X-PAYMENT-RESPONSE", + }, + }); + + if (response.ok) { + await onSuccessfulResponse(response); + return; + } + + if (response.status === 402) { + const errorData = await response.json().catch(() => ({})); + if (errorData && typeof errorData.x402Version === "number") { + const retryPayment = await exact.svm.createPaymentHeader( + walletSigner, + errorData.x402Version, + validPaymentRequirements, + ); + + const retryResponse = await fetch(x402.currentUrl, { + headers: { + "X-PAYMENT": retryPayment, + "Access-Control-Expose-Headers": "X-PAYMENT-RESPONSE", + }, + }); + + if (retryResponse.ok) { + await onSuccessfulResponse(retryResponse); + return; + } + + throw new Error( + `Payment retry failed: ${retryResponse.status} ${retryResponse.statusText}`, + ); + } + + throw new Error(`Payment failed: ${response.statusText}`); + } + + throw new Error(`Payment failed: ${response.status} ${response.statusText}`); + } catch (error) { + setStatus(error instanceof Error ? error.message : "Payment failed."); + } finally { + setIsPaying(false); + } + }, [ + x402, + walletSigner, + activeAccount, + usdcBalance, + refreshBalance, + chainName, + paymentRequirement, + onSuccessfulResponse, + ]); + + return ( +
+
+

Payment Required

+

+ {paymentRequirement.description && `${paymentRequirement.description}.`} To access this + content, please pay ${amount} {chainName} USDC. +

+ {network === "solana-devnet" && ( +

+ Need Solana Devnet USDC?{" "} + + Request some here. + +

+ )} +
+ +
+
+
+ Wallet: + + {activeAccount + ? `${activeAccount.address.slice(0, 6)}...${activeAccount.address.slice(-4)}` + : "-"} + +
+
+ Available balance: + + {activeAccount ? ( + + ) : ( + "-" + )} + +
+
+ Amount: + ${amount} USDC +
+
+ Network: + {chainName} +
+
+ +
+ {activeAccount ? ( + + ) : ( + <> + + + + )} + {activeAccount && ( + + )} +
+ + {!walletOptions.length && ( +
+ Install a Solana wallet such as Phantom to continue, then refresh this page. +
+ )} + + {status &&
{status}
} +
+
+ ); +} diff --git a/typescript/packages/http/paywall/src/svm/Spinner.tsx b/typescript/packages/http/paywall/src/svm/Spinner.tsx new file mode 100644 index 000000000..905785c42 --- /dev/null +++ b/typescript/packages/http/paywall/src/svm/Spinner.tsx @@ -0,0 +1,20 @@ +/** + * Simple Spinner component for loading states + * + * @param props - The component props + * @param props.className - Optional CSS classes to apply to the spinner + * @returns The Spinner component + */ +export function Spinner({ className = "" }: { className?: string }) { + return ( +
+
+
+ ); +} diff --git a/typescript/packages/http/paywall/src/svm/build.ts b/typescript/packages/http/paywall/src/svm/build.ts new file mode 100644 index 000000000..dc4d1d1fc --- /dev/null +++ b/typescript/packages/http/paywall/src/svm/build.ts @@ -0,0 +1,90 @@ +import esbuild from "esbuild"; +import { htmlPlugin } from "@craftamap/esbuild-plugin-html"; +import fs from "fs"; +import path from "path"; +import { getBaseTemplate } from "../baseTemplate"; + +// SVM-specific build - only bundles Solana dependencies +const DIST_DIR = "src/svm/dist"; +const OUTPUT_HTML = path.join(DIST_DIR, "svm-paywall.html"); +const OUTPUT_TS = path.join("src/svm/gen", "template.ts"); + +const options: esbuild.BuildOptions = { + entryPoints: ["src/svm/index.tsx", "src/styles.css"], + bundle: true, + metafile: true, + outdir: DIST_DIR, + treeShaking: true, + minify: true, + format: "iife", + sourcemap: false, + platform: "browser", + target: "es2020", + jsx: "transform", + define: { + "process.env.NODE_ENV": '"development"', + global: "globalThis", + Buffer: "globalThis.Buffer", + }, + mainFields: ["browser", "module", "main"], + conditions: ["browser"], + plugins: [ + htmlPlugin({ + files: [ + { + entryPoints: ["src/svm/index.tsx", "src/styles.css"], + filename: "svm-paywall.html", + title: "Payment Required", + scriptLoading: "module", + inline: { + css: true, + js: true, + }, + htmlTemplate: getBaseTemplate(), + }, + ], + }), + ], + inject: ["./src/buffer-polyfill.ts"], + external: ["crypto"], +}; + +/** + * Builds the SVM paywall HTML template with bundled JS and CSS. + */ +async function build() { + try { + if (!fs.existsSync(DIST_DIR)) { + fs.mkdirSync(DIST_DIR, { recursive: true }); + } + + const genDir = path.dirname(OUTPUT_TS); + if (!fs.existsSync(genDir)) { + fs.mkdirSync(genDir, { recursive: true }); + } + + await esbuild.build(options); + console.log("[SVM] Build completed successfully!"); + + if (fs.existsSync(OUTPUT_HTML)) { + const html = fs.readFileSync(OUTPUT_HTML, "utf8"); + + const tsContent = `// THIS FILE IS AUTO-GENERATED - DO NOT EDIT +/** + * The pre-built SVM paywall template with inlined CSS and JS + */ +export const SVM_PAYWALL_TEMPLATE = ${JSON.stringify(html)}; +`; + + fs.writeFileSync(OUTPUT_TS, tsContent); + console.log(`[SVM] Generated template.ts (${(html.length / 1024 / 1024).toFixed(2)} MB)`); + } else { + throw new Error(`SVM bundled HTML not found at ${OUTPUT_HTML}`); + } + } catch (error) { + console.error("[SVM] Build failed:", error); + process.exit(1); + } +} + +build(); diff --git a/typescript/packages/http/paywall/src/svm/gen/template.ts b/typescript/packages/http/paywall/src/svm/gen/template.ts new file mode 100644 index 000000000..c144274d7 --- /dev/null +++ b/typescript/packages/http/paywall/src/svm/gen/template.ts @@ -0,0 +1,5 @@ +// THIS FILE IS AUTO-GENERATED - DO NOT EDIT +/** + * The pre-built SVM paywall template with inlined CSS and JS + */ +export const SVM_PAYWALL_TEMPLATE = "\n \n \n Payment Required\n \n
\n \n \n "; diff --git a/typescript/packages/http/paywall/src/svm/index.ts b/typescript/packages/http/paywall/src/svm/index.ts new file mode 100644 index 000000000..79d7008ae --- /dev/null +++ b/typescript/packages/http/paywall/src/svm/index.ts @@ -0,0 +1,71 @@ +import type { + PaywallNetworkHandler, + PaymentRequirements, + PaymentRequired, + PaywallConfig, +} from "../types"; +import { getSvmPaywallHtml } from "./paywall"; +import { SVM_NETWORKS, type SVMNetworkV1 } from "@x402/core/types"; + +/** + * SVM paywall handler that supports Solana-based networks + */ +export const svmPaywall: PaywallNetworkHandler = { + /** + * Check if this handler supports the given payment requirement + * + * @param x402Version - The x402 protocol version + * @param requirement - Payment requirement to check + * @returns True if this handler can process this requirement + */ + supports(x402Version: number, requirement: PaymentRequirements): boolean { + const network = requirement.network; + + if (x402Version === 2) { + // v2: CAIP-2 format (solana:*) + return network.startsWith("solana:"); + } + + if (x402Version === 1) { + // v1: legacy network names + return SVM_NETWORKS.includes(network as SVMNetworkV1); + } + + return false; + }, + + /** + * Generate SVM-specific paywall HTML + * + * @param requirement - The selected payment requirement + * @param paymentRequired - Full payment required response + * @param config - Paywall configuration + * @returns HTML string for the paywall page + */ + generateHtml( + requirement: PaymentRequirements, + paymentRequired: PaymentRequired, + config: PaywallConfig, + ): string { + // Calculate display amount + const amount = requirement.amount + ? parseFloat(requirement.amount) / 1000000 + : requirement.maxAmountRequired + ? parseFloat(requirement.maxAmountRequired) / 1000000 + : 0; + + return getSvmPaywallHtml({ + amount, + paymentRequirements: [requirement], + currentUrl: paymentRequired.resource?.url || config.currentUrl || "", + testnet: config.testnet ?? true, + cdpClientKey: config.cdpClientKey, + appName: config.appName, + appLogo: config.appLogo, + sessionTokenEndpoint: config.sessionTokenEndpoint, + }); + }, +}; + +// Also export components for custom UI builders +export { SolanaPaywall } from "./SolanaPaywall"; diff --git a/typescript/packages/http/paywall/src/svm/index.tsx b/typescript/packages/http/paywall/src/svm/index.tsx new file mode 100644 index 000000000..ad13c3c40 --- /dev/null +++ b/typescript/packages/http/paywall/src/svm/index.tsx @@ -0,0 +1,31 @@ +import React from "react"; +import { createRoot } from "react-dom/client"; +import { SolanaPaywall } from "./SolanaPaywall"; + +// SVM-specific paywall entry point +window.addEventListener("load", () => { + const rootElement = document.getElementById("root"); + if (!rootElement) { + console.error("Root element not found"); + return; + } + + const x402 = window.x402; + + const root = createRoot(rootElement); + root.render( + { + const contentType = response.headers.get("content-type"); + if (contentType && contentType.includes("text/html")) { + document.documentElement.innerHTML = await response.text(); + } else { + const blob = await response.blob(); + const url = window.URL.createObjectURL(blob); + window.location.href = url; + } + }} + />, + ); +}); diff --git a/typescript/packages/http/paywall/src/svm/paywall.ts b/typescript/packages/http/paywall/src/svm/paywall.ts new file mode 100644 index 000000000..fcd6cd6e4 --- /dev/null +++ b/typescript/packages/http/paywall/src/svm/paywall.ts @@ -0,0 +1,83 @@ +import type { PaymentRequirements } from "../types"; + +/** + * Escapes a string for safe injection into JavaScript string literals + * + * @param str - The string to escape + * @returns The escaped string + */ +function escapeString(str: string): string { + return str + .replace(/\\/g, "\\\\") + .replace(/"/g, '\\"') + .replace(/'/g, "\\'") + .replace(/\n/g, "\\n") + .replace(/\r/g, "\\r") + .replace(/\t/g, "\\t"); +} + +interface SvmPaywallOptions { + amount: number; + paymentRequirements: PaymentRequirements[]; + currentUrl: string; + testnet: boolean; + cdpClientKey?: string; + appName?: string; + appLogo?: string; + sessionTokenEndpoint?: string; +} + +/** + * Generates SVM-specific paywall HTML + * + * @param options - The options for generating the paywall + * @returns HTML string for the paywall page + */ +export function getSvmPaywallHtml(options: SvmPaywallOptions): string { + let SVM_PAYWALL_TEMPLATE: string; + + try { + // Will be generated by build script + // eslint-disable-next-line @typescript-eslint/no-require-imports + const template = require("./gen/template"); + SVM_PAYWALL_TEMPLATE = template.SVM_PAYWALL_TEMPLATE; + } catch { + // Template not built yet, return placeholder + return `

SVM Paywall (run pnpm build:paywall to generate full template)

`; + } + + const { + amount, + testnet, + paymentRequirements, + currentUrl, + cdpClientKey, + appName, + appLogo, + sessionTokenEndpoint, + } = options; + + const logOnTestnet = testnet + ? "console.log('SVM Payment requirements initialized:', window.x402);" + : ""; + + const configScript = ` + `; + + return SVM_PAYWALL_TEMPLATE.replace("", `${configScript}\n`); +} diff --git a/typescript/packages/http/paywall/src/svm/solana/features.ts b/typescript/packages/http/paywall/src/svm/solana/features.ts new file mode 100644 index 000000000..5c3574dc6 --- /dev/null +++ b/typescript/packages/http/paywall/src/svm/solana/features.ts @@ -0,0 +1,61 @@ +import { + StandardConnect, + StandardDisconnect, + StandardEvents, + type StandardConnectFeature, + type StandardDisconnectFeature, + type StandardEventsFeature, +} from "@wallet-standard/features"; +import { + SolanaSignTransaction, + type SolanaSignTransactionFeature, + type WalletWithSolanaFeatures, +} from "@solana/wallet-standard-features"; +import type { Wallet } from "@wallet-standard/base"; + +/** + * Type guard ensuring the wallet implements the Solana signing features. + * + * @param wallet - Wallet instance to inspect. + * @returns True when the wallet supports Solana signing. + */ +export const hasSolanaSigning = (wallet: Wallet): wallet is WalletWithSolanaFeatures => + SolanaSignTransaction in wallet.features; + +/** + * Extracts the Solana transaction signing feature when present. + * + * @param wallet - Wallet that may expose the signing capability. + * @returns The signing feature if available, otherwise undefined. + */ +export const getSolanaSignTransactionFeature = (wallet: WalletWithSolanaFeatures) => + (wallet.features as unknown as Partial)[SolanaSignTransaction]; + +/** + * Retrieves the standard connect feature from a wallet, if supported. + * + * @param wallet - Wallet under inspection. + * @returns The connect feature when present. + */ +export const getStandardConnectFeature = (wallet: WalletWithSolanaFeatures) => + (wallet.features as unknown as Partial)[StandardConnect]; + +/** + * Retrieves the standard events feature from a wallet, if supported. + * + * @param wallet - Wallet under inspection. + * @returns The events feature when present. + */ +export const getStandardEventsFeature = (wallet: WalletWithSolanaFeatures) => + (wallet.features as unknown as Partial)[StandardEvents]; + +/** + * Retrieves the standard disconnect feature from a wallet, if supported. + * + * @param wallet - Wallet under inspection. + * @returns The disconnect feature when present. + */ +export const getStandardDisconnectFeature = (wallet: WalletWithSolanaFeatures) => + (wallet.features as unknown as Partial)[StandardDisconnect]; + +export type { StandardEventsChangeProperties } from "@wallet-standard/features"; diff --git a/typescript/packages/http/paywall/src/svm/solana/rpc.ts b/typescript/packages/http/paywall/src/svm/solana/rpc.ts new file mode 100644 index 000000000..71820d45b --- /dev/null +++ b/typescript/packages/http/paywall/src/svm/solana/rpc.ts @@ -0,0 +1,66 @@ +import { + createSolanaRpc, + devnet, + mainnet, + RpcDevnet, + SolanaRpcApiDevnet, + SolanaRpcApiMainnet, + RpcMainnet, +} from "@solana/kit"; + +/** + * Default public RPC endpoint for Solana devnet + */ +const DEVNET_RPC_URL = "https://api.devnet.solana.com"; + +/** + * Default public RPC endpoint for Solana mainnet + */ +const MAINNET_RPC_URL = "https://api.mainnet-beta.solana.com"; + +/** + * Creates a Solana RPC client for the devnet network. + * + * @param url - Optional URL of the devnet network. + * @returns A Solana RPC client. + */ +export function createDevnetRpcClient(url?: string): RpcDevnet { + return createSolanaRpc( + url ? devnet(url) : devnet(DEVNET_RPC_URL), + ) as RpcDevnet; +} + +/** + * Creates a Solana RPC client for the mainnet network. + * + * @param url - Optional URL of the mainnet network. + * @returns A Solana RPC client. + */ +export function createMainnetRpcClient(url?: string): RpcMainnet { + return createSolanaRpc( + url ? mainnet(url) : mainnet(MAINNET_RPC_URL), + ) as RpcMainnet; +} + +/** + * Gets the RPC client for the given network. + * + * @param network - The network to get the RPC client for + * @param url - Optional URL of the network. If not provided, the default URL will be used. + * @returns The RPC client for the given network + */ +export function getRpcClient( + network: string, + url?: string, +): RpcDevnet | RpcMainnet { + if ( + network === "solana-devnet" || + (network.startsWith("solana:") && network.includes("devnet")) + ) { + return createDevnetRpcClient(url); + } else if (network === "solana" || network.startsWith("solana:")) { + return createMainnetRpcClient(url); + } else { + throw new Error("Invalid network"); + } +} diff --git a/typescript/packages/http/paywall/src/svm/solana/types.ts b/typescript/packages/http/paywall/src/svm/solana/types.ts new file mode 100644 index 000000000..ee09f11da --- /dev/null +++ b/typescript/packages/http/paywall/src/svm/solana/types.ts @@ -0,0 +1,6 @@ +import type { WalletWithSolanaFeatures } from "@solana/wallet-standard-features"; + +export type WalletOption = { + value: string; + wallet: WalletWithSolanaFeatures; +}; diff --git a/typescript/packages/http/paywall/src/svm/solana/useSilentWalletConnection.ts b/typescript/packages/http/paywall/src/svm/solana/useSilentWalletConnection.ts new file mode 100644 index 000000000..65a340627 --- /dev/null +++ b/typescript/packages/http/paywall/src/svm/solana/useSilentWalletConnection.ts @@ -0,0 +1,97 @@ +import { useEffect } from "react"; +import type { MutableRefObject } from "react"; +import type { WalletAccount } from "@wallet-standard/base"; +import type { WalletWithSolanaFeatures } from "@solana/wallet-standard-features"; + +import { getStandardConnectFeature } from "./features"; +import type { WalletOption } from "./types"; + +type Params = { + walletOptions: WalletOption[]; + activeWallet: WalletWithSolanaFeatures | null; + targetChain: "solana:mainnet" | "solana:devnet"; + attemptedSilentConnectWalletsRef: MutableRefObject>; + setSelectedWalletValue: (value: string) => void; + setActiveWallet: (wallet: WalletWithSolanaFeatures | null) => void; + setActiveAccount: (account: WalletAccount | null) => void; + refreshBalance: (account?: WalletAccount | null) => Promise; + setStatus: (message: string) => void; +}; + +/** + * Attempts a silent connection with available wallets to restore prior authorization. + * + * @param params - Hook parameters controlling wallet state and callbacks. + * @param params.walletOptions - Wallets eligible for silent reconnection. + * @param params.activeWallet - Currently active wallet, if any. + * @param params.targetChain - Solana chain identifier targeted by the paywall. + * @param params.attemptedSilentConnectWalletsRef - Ref tracking wallets already attempted silently. + * @param params.setSelectedWalletValue - Setter for the currently selected wallet option. + * @param params.setActiveWallet - Setter storing the active wallet instance. + * @param params.setActiveAccount - Setter storing the active wallet account. + * @param params.refreshBalance - Callback used to refresh the USDC balance. + * @param params.setStatus - Setter used to surface user-visible status messages. + */ +export function useSilentWalletConnection({ + walletOptions, + activeWallet, + targetChain, + attemptedSilentConnectWalletsRef, + setSelectedWalletValue, + setActiveWallet, + setActiveAccount, + refreshBalance, + setStatus, +}: Params): void { + useEffect(() => { + if (activeWallet) { + return; + } + + for (const option of walletOptions) { + if (attemptedSilentConnectWalletsRef.current.has(option.value)) { + continue; + } + + attemptedSilentConnectWalletsRef.current.add(option.value); + const connectFeature = getStandardConnectFeature(option.wallet); + if (!connectFeature) { + continue; + } + + void (async () => { + try { + const { accounts } = await connectFeature.connect({ silent: true }); + if (!accounts?.length) { + return; + } + + const matchingAccount = + accounts.find((account: WalletAccount) => account.chains?.includes(targetChain)) ?? + accounts[0]; + if (!matchingAccount) { + return; + } + + setSelectedWalletValue(option.value); + setActiveWallet(option.wallet); + setActiveAccount(matchingAccount); + setStatus(""); + await refreshBalance(matchingAccount); + } catch { + // Wallet may throw if silent connect isn't supported or authorization is missing. Ignore. + } + })(); + } + }, [ + walletOptions, + activeWallet, + targetChain, + attemptedSilentConnectWalletsRef, + setSelectedWalletValue, + setActiveWallet, + setActiveAccount, + refreshBalance, + setStatus, + ]); +} diff --git a/typescript/packages/http/paywall/src/svm/solana/useSolanaBalance.ts b/typescript/packages/http/paywall/src/svm/solana/useSolanaBalance.ts new file mode 100644 index 000000000..1787fbcf4 --- /dev/null +++ b/typescript/packages/http/paywall/src/svm/solana/useSolanaBalance.ts @@ -0,0 +1,116 @@ +import { useCallback, useEffect, useState } from "react"; +import { formatUnits } from "viem"; +import type { WalletAccount } from "@wallet-standard/base"; +import type { PaymentRequirements } from "x402/types"; +import { getRpcClient } from "./rpc"; +import type { Address } from "@solana/kit"; +import { + TOKEN_PROGRAM_ADDRESS, + fetchMaybeToken as fetchMaybeSplToken, +} from "@solana-program/token"; +import { + TOKEN_2022_PROGRAM_ADDRESS, + fetchMaybeToken as fetchMaybeToken2022, + fetchMint, + findAssociatedTokenPda, +} from "@solana-program/token-2022"; +import { address as toAddress } from "@solana/kit"; + +type Params = { + activeAccount: WalletAccount | null; + paymentRequirement: PaymentRequirements; + onStatus: (message: string) => void; +}; + +type BalanceState = { + usdcBalance: bigint | null; + formattedBalance: string; + isFetchingBalance: boolean; + refreshBalance: (account?: WalletAccount | null) => Promise; + resetBalance: () => void; +}; + +/** + * Tracks and refreshes the Solana USDC balance for the active account. + * + * @param params - Hook parameters containing account details and callbacks. + * @param params.activeAccount - Wallet account whose balance is being tracked. + * @param params.paymentRequirement - Payment requirement describing the asset to monitor. + * @param params.onStatus - Callback for reporting status messages to the UI. + * @returns Balance state and helper methods for refreshing/resetting data. + */ +export function useSolanaBalance({ + activeAccount, + paymentRequirement, + onStatus, +}: Params): BalanceState { + const [usdcBalance, setUsdcBalance] = useState(null); + const [formattedBalance, setFormattedBalance] = useState(""); + const [isFetchingBalance, setIsFetchingBalance] = useState(false); + + const resetBalance = useCallback(() => { + setUsdcBalance(null); + setFormattedBalance(""); + }, []); + + const refreshBalance = useCallback( + async (account: WalletAccount | null = activeAccount) => { + if (!account) { + resetBalance(); + return null; + } + + try { + setIsFetchingBalance(true); + + const rpc = getRpcClient(paymentRequirement.network); + const mint = await fetchMint(rpc, paymentRequirement.asset as Address); + const tokenProgramAddress = mint.programAddress; + const [ata] = await findAssociatedTokenPda({ + mint: paymentRequirement.asset as Address, + owner: toAddress(account.address), + tokenProgram: tokenProgramAddress, + }); + + let balance = 0n; + if (tokenProgramAddress.toString() === TOKEN_PROGRAM_ADDRESS.toString()) { + const tokenAccount = await fetchMaybeSplToken(rpc, ata); + if (tokenAccount.exists) { + balance = tokenAccount.data.amount; + } + } else if (tokenProgramAddress.toString() === TOKEN_2022_PROGRAM_ADDRESS.toString()) { + const tokenAccount = await fetchMaybeToken2022(rpc, ata); + if (tokenAccount.exists) { + balance = tokenAccount.data.amount; + } + } + + setUsdcBalance(balance); + setFormattedBalance(formatUnits(balance, mint.data.decimals)); + return balance; + } catch (error) { + console.error("Failed to fetch Solana USDC balance", error); + onStatus("Unable to read your USDC balance. Please retry."); + resetBalance(); + return null; + } finally { + setIsFetchingBalance(false); + } + }, + [activeAccount, paymentRequirement, onStatus, resetBalance], + ); + + useEffect(() => { + if (activeAccount) { + void refreshBalance(); + } + }, [activeAccount, refreshBalance]); + + return { + usdcBalance, + formattedBalance, + isFetchingBalance, + refreshBalance, + resetBalance, + }; +} diff --git a/typescript/packages/http/paywall/src/svm/solana/useSolanaSigner.ts b/typescript/packages/http/paywall/src/svm/solana/useSolanaSigner.ts new file mode 100644 index 000000000..8bc90c9eb --- /dev/null +++ b/typescript/packages/http/paywall/src/svm/solana/useSolanaSigner.ts @@ -0,0 +1,79 @@ +import { useMemo } from "react"; +import { + getTransactionDecoder, + getTransactionEncoder, + type SignatureDictionary, + type TransactionSigner, + address as toAddress, +} from "@solana/kit"; +import type { WalletAccount } from "@wallet-standard/base"; +import type { WalletWithSolanaFeatures } from "@solana/wallet-standard-features"; + +import { getSolanaSignTransactionFeature } from "./features"; + +type Params = { + activeWallet: WalletWithSolanaFeatures | null; + activeAccount: WalletAccount | null; + targetChain: "solana:mainnet" | "solana:devnet"; +}; + +/** + * Derives a transaction signer that proxies requests to the connected Solana wallet. + * + * @param params - Hook parameters defining the active wallet/account and chain target. + * @param params.activeWallet - Wallet currently selected by the user. + * @param params.activeAccount - Account inside the wallet authorised for signing. + * @param params.targetChain - Identifier of the Solana cluster to sign transactions for. + * @returns A transaction signer or null when the wallet cannot sign. + */ +export function useSolanaSigner({ + activeWallet, + activeAccount, + targetChain, +}: Params): TransactionSigner | null { + return useMemo(() => { + if (!activeWallet || !activeAccount) { + return null; + } + + const signFeature = getSolanaSignTransactionFeature(activeWallet); + if (!signFeature) { + return null; + } + + const signerAddress = toAddress(activeAccount.address); + const encoder = getTransactionEncoder(); + const decoder = getTransactionDecoder(); + + return { + address: signerAddress, + async signTransactions(transactions) { + const signatures: SignatureDictionary[] = []; + + for (const transaction of transactions) { + const serialized = new Uint8Array(encoder.encode(transaction)); + const [signed] = await signFeature.signTransaction({ + account: activeAccount, + transaction: serialized, + chain: targetChain, + }); + + const decodedTransaction = decoder.decode(new Uint8Array(signed.signedTransaction)); + const signature = decodedTransaction.signatures[signerAddress]; + + if (!signature) { + throw new Error("Wallet did not return a signature for the selected account."); + } + + signatures.push( + Object.freeze({ + [signerAddress]: signature, + }) as SignatureDictionary, + ); + } + + return signatures; + }, + }; + }, [activeWallet, activeAccount, targetChain]); +} diff --git a/typescript/packages/http/paywall/src/svm/solana/useSolanaWalletEvents.ts b/typescript/packages/http/paywall/src/svm/solana/useSolanaWalletEvents.ts new file mode 100644 index 000000000..f99d40a27 --- /dev/null +++ b/typescript/packages/http/paywall/src/svm/solana/useSolanaWalletEvents.ts @@ -0,0 +1,113 @@ +import { useEffect } from "react"; +import type { WalletAccount } from "@wallet-standard/base"; +import type { WalletWithSolanaFeatures } from "@solana/wallet-standard-features"; + +import { SolanaSignTransaction } from "@solana/wallet-standard-features"; + +import { getStandardEventsFeature, type StandardEventsChangeProperties } from "./features"; + +type Params = { + activeWallet: WalletWithSolanaFeatures | null; + targetChain: "solana:mainnet" | "solana:devnet"; + chainName: string; + setActiveWallet: (wallet: WalletWithSolanaFeatures | null) => void; + setActiveAccount: (account: WalletAccount | null) => void; + setSelectedWalletValue: (value: string) => void; + setStatus: (status: string) => void; + resetBalance: () => void; + refreshBalance: (account?: WalletAccount | null) => Promise; +}; + +/** + * Listens for wallet-standard change events and keeps local state in sync. + * + * @param params - Hook parameters describing wallet state handlers and dependencies. + * @param params.activeWallet - Wallet currently active in the UI. + * @param params.targetChain - Chain identifier expected for the session. + * @param params.chainName - Human-readable name of the active chain. + * @param params.setActiveWallet - Setter used to store the active wallet. + * @param params.setActiveAccount - Setter used to store the active account. + * @param params.setSelectedWalletValue - Setter for the selected wallet option value. + * @param params.setStatus - Setter for user-facing status messages. + * @param params.resetBalance - Helper to clear cached balance state. + * @param params.refreshBalance - Function that refreshes the cached balance. + */ +export function useSolanaWalletEvents({ + activeWallet, + targetChain, + chainName, + setActiveWallet, + setActiveAccount, + setSelectedWalletValue, + setStatus, + resetBalance, + refreshBalance, +}: Params): void { + useEffect(() => { + if (!activeWallet) { + return; + } + + const eventsFeature = getStandardEventsFeature(activeWallet); + if (!eventsFeature) { + return; + } + + const unsubscribe = eventsFeature.on("change", (properties: StandardEventsChangeProperties) => { + if (properties.features && !(SolanaSignTransaction in properties.features)) { + setActiveWallet(null); + setActiveAccount(null); + setSelectedWalletValue(""); + resetBalance(); + setStatus("Selected wallet no longer supports Solana signing. Please reconnect."); + return; + } + + if (properties.accounts) { + if (!properties.accounts.length) { + setActiveAccount(null); + resetBalance(); + setStatus("Wallet disconnected. Select a wallet to reconnect."); + return; + } + + const nextAccount = + properties.accounts.find((account: WalletAccount) => + account.chains?.includes(targetChain), + ) ?? + properties.accounts[0] ?? + null; + + setActiveAccount(nextAccount); + + if (!nextAccount) { + setStatus("No authorized Solana accounts available. Reconnect your wallet."); + resetBalance(); + return; + } + + if (nextAccount.chains?.includes(targetChain)) { + setStatus(""); + } else { + setStatus(`Switch your wallet to ${chainName} to continue.`); + } + + void refreshBalance(nextAccount); + } + }); + + return () => { + unsubscribe(); + }; + }, [ + activeWallet, + targetChain, + chainName, + setActiveWallet, + setActiveAccount, + setSelectedWalletValue, + setStatus, + resetBalance, + refreshBalance, + ]); +} diff --git a/typescript/packages/http/paywall/src/svm/solana/useSolanaWalletOptions.ts b/typescript/packages/http/paywall/src/svm/solana/useSolanaWalletOptions.ts new file mode 100644 index 000000000..13f04427b --- /dev/null +++ b/typescript/packages/http/paywall/src/svm/solana/useSolanaWalletOptions.ts @@ -0,0 +1,43 @@ +import { useEffect, useState } from "react"; +import { getWallets } from "@wallet-standard/app"; + +import { hasSolanaSigning } from "./features"; +import type { WalletOption } from "./types"; + +/** + * Subscribes to wallet-standard registrations and collects Solana-capable wallets. + * + * @returns Wallet options suitable for Solana interactions. + */ +export function useSolanaWalletOptions(): WalletOption[] { + const [walletOptions, setWalletOptions] = useState([]); + + useEffect(() => { + const walletsApi = getWallets(); + + const mapWallets = (): WalletOption[] => + walletsApi + .get() + .filter(hasSolanaSigning) + .map(wallet => ({ + value: wallet.name, + wallet, + })); + + setWalletOptions(mapWallets()); + + const offRegister = walletsApi.on("register", () => { + setWalletOptions(mapWallets()); + }); + const offUnregister = walletsApi.on("unregister", () => { + setWalletOptions(mapWallets()); + }); + + return () => { + offRegister(); + offUnregister(); + }; + }, []); + + return walletOptions; +} diff --git a/typescript/packages/http/paywall/src/types.ts b/typescript/packages/http/paywall/src/types.ts new file mode 100644 index 000000000..903ef37d7 --- /dev/null +++ b/typescript/packages/http/paywall/src/types.ts @@ -0,0 +1,87 @@ +/** + * Configuration options for the paywall + */ +export interface PaywallConfig { + cdpClientKey?: string; + appName?: string; + appLogo?: string; + sessionTokenEndpoint?: string; + currentUrl?: string; + testnet?: boolean; +} + +/** + * Payment requirements structure (supports both v1 and v2) + */ +export interface PaymentRequirements { + scheme: string; + network: string; + asset: string; + payTo: string; + maxTimeoutSeconds: number; + extra?: Record; + // V1 fields + maxAmountRequired?: string; + description?: string; + resource?: string; + mimeType?: string; + // V2 fields + amount?: string; +} + +/** + * Payment required response structure + */ +export interface PaymentRequired { + x402Version: number; + error?: string; + resource?: { + url: string; + description: string; + mimeType: string; + }; + accepts: PaymentRequirements[]; + extensions?: Record; +} + +/** + * Paywall provider interface for generating HTML + */ +export interface PaywallProvider { + /** + * Generate HTML for a payment required response + * + * @param paymentRequired - Payment required response with accepts array + * @param config - Optional runtime configuration + * @returns HTML string for the paywall page + */ + generateHtml(paymentRequired: PaymentRequired, config?: PaywallConfig): string; +} + +/** + * Network-specific paywall handler + */ +export interface PaywallNetworkHandler { + /** + * Check if this handler supports the given payment requirement + * + * @param x402Version - The x402 protocol version + * @param requirement - Payment requirement to check + * @returns True if this handler can process this requirement + */ + supports(x402Version: number, requirement: PaymentRequirements): boolean; + + /** + * Generate HTML for this network's paywall + * + * @param requirement - The selected payment requirement + * @param paymentRequired - Full payment required response + * @param config - Paywall configuration + * @returns HTML string for the paywall page + */ + generateHtml( + requirement: PaymentRequirements, + paymentRequired: PaymentRequired, + config: PaywallConfig, + ): string; +} diff --git a/typescript/packages/http/paywall/src/utils.ts b/typescript/packages/http/paywall/src/utils.ts new file mode 100644 index 000000000..108f91d99 --- /dev/null +++ b/typescript/packages/http/paywall/src/utils.ts @@ -0,0 +1,149 @@ +import type { PaymentRequirements, PaymentRequirementsV1 } from "@x402/core/types"; + +/** + * Safely clones an object without prototype pollution + * + * @param obj - The object to clone + * @returns A safe clone of the object + */ +function safeClone(obj: T): T { + if (obj === null || typeof obj !== "object") { + return obj; + } + + if (obj instanceof Date) { + return new Date(obj.getTime()) as T; + } + + if (Array.isArray(obj)) { + return obj.map(item => safeClone(item)) as T; + } + + const cloned: Record = {}; + for (const key in obj as Record) { + // Skip __proto__ and other dangerous properties + if (key === "__proto__" || key === "constructor" || key === "prototype") { + continue; + } + if (Object.prototype.hasOwnProperty.call(obj, key)) { + cloned[key] = safeClone((obj as Record)[key]); + } + } + return cloned as T; +} + +/** + * Ensures a valid amount is set in payment requirements (v2) + * + * @param paymentRequirements - The payment requirements to validate and update + * @returns Updated payment requirements with valid amount + */ +function ensureValidAmountV2(paymentRequirements: PaymentRequirements): PaymentRequirements { + const updatedRequirements = safeClone(paymentRequirements); + + if (window.x402?.amount) { + try { + const amountInBaseUnits = Math.round(window.x402.amount * 1_000_000); + updatedRequirements.amount = amountInBaseUnits.toString(); + } catch (error) { + console.error("Failed to parse amount:", error); + } + } + + const hasValidAmount = + updatedRequirements.amount && + typeof updatedRequirements.amount === "string" && + /^\d+$/.test(updatedRequirements.amount); + + if (!hasValidAmount) { + throw new Error("Invalid or missing amount in payment requirements"); + } + + return updatedRequirements; +} + +/** + * Ensures a valid amount is set in payment requirements (v1) + * + * @param paymentRequirements - The payment requirements to validate and update + * @returns Updated payment requirements with valid amount + */ +function ensureValidAmountV1(paymentRequirements: PaymentRequirementsV1): PaymentRequirementsV1 { + const updatedRequirements = safeClone(paymentRequirements); + + if (window.x402?.amount) { + try { + const amountInBaseUnits = Math.round(window.x402.amount * 1_000_000); + updatedRequirements.maxAmountRequired = amountInBaseUnits.toString(); + } catch (error) { + console.error("Failed to parse amount:", error); + } + } + + const hasValidAmount = + updatedRequirements.maxAmountRequired && + typeof updatedRequirements.maxAmountRequired === "string" && + /^\d+$/.test(updatedRequirements.maxAmountRequired); + + if (!hasValidAmount) { + throw new Error("Invalid or missing maxAmountRequired in payment requirements"); + } + + return updatedRequirements; +} + +/** + * Ensures a valid amount is set in payment requirements + * + * @param x402Version - The x402 protocol version + * @param paymentRequirements - The payment requirements to validate and update + * @returns Updated payment requirements with valid amount + */ +export function ensureValidAmount( + x402Version: number, + paymentRequirements: PaymentRequirements | PaymentRequirementsV1, +): PaymentRequirements | PaymentRequirementsV1 { + switch (x402Version) { + case 1: + return ensureValidAmountV1(paymentRequirements as PaymentRequirementsV1); + case 2: + default: + return ensureValidAmountV2(paymentRequirements as PaymentRequirements); + } +} + +/** + * Generates a session token for the user + * + * @param address - The user's connected wallet address + * @returns The session token + */ +export const generateOnrampSessionToken = async (address: string): Promise => { + const endpoint = window.x402?.sessionTokenEndpoint; + if (!endpoint) { + return undefined; + } + + try { + // Call the session token API with user's address + const response = await fetch(endpoint, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + addresses: [ + { + address, + blockchains: ["base"], // Onramp only supports mainnet + }, + ], + assets: ["USDC"], + }), + }); + + const data = await response.json(); + return data.token; + } catch (error) { + console.error("Failed to generate onramp session token:", error); + return undefined; + } +}; diff --git a/typescript/packages/http/paywall/src/window.d.ts b/typescript/packages/http/paywall/src/window.d.ts new file mode 100644 index 000000000..a3a8318e3 --- /dev/null +++ b/typescript/packages/http/paywall/src/window.d.ts @@ -0,0 +1,25 @@ +import { PaymentRequirements } from "@x402/core"; + +declare global { + interface Window { + x402: { + amount?: number; + testnet?: boolean; + paymentRequirements: PaymentRequirements | PaymentRequirements[]; + currentUrl: string; + cdpClientKey?: string; + appName?: string; + appLogo?: string; + sessionTokenEndpoint?: string; + config: { + chainConfig: Record< + string, + { + usdcAddress: string; + usdcName: string; + } + >; + }; + }; + } +} diff --git a/typescript/packages/http/paywall/tsconfig.json b/typescript/packages/http/paywall/tsconfig.json new file mode 100644 index 000000000..47d9afe37 --- /dev/null +++ b/typescript/packages/http/paywall/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "allowJs": false, + "checkJs": false, + "jsx": "react-jsx", + "lib": ["ES2020", "DOM", "DOM.Iterable"] + }, + "include": ["src"] +} diff --git a/typescript/packages/http/paywall/tsup.config.ts b/typescript/packages/http/paywall/tsup.config.ts new file mode 100644 index 000000000..433587d5c --- /dev/null +++ b/typescript/packages/http/paywall/tsup.config.ts @@ -0,0 +1,16 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: { + index: "src/index.ts", + "evm/index": "src/evm/index.ts", + "svm/index": "src/svm/index.ts", + }, + format: ["cjs", "esm"], + dts: true, + splitting: false, + sourcemap: true, + clean: true, + external: ["react", "react-dom"], + treeshake: true, +}); diff --git a/typescript/packages/http/paywall/vitest.config.ts b/typescript/packages/http/paywall/vitest.config.ts new file mode 100644 index 000000000..156f8c924 --- /dev/null +++ b/typescript/packages/http/paywall/vitest.config.ts @@ -0,0 +1,10 @@ +import { loadEnv } from "vite"; +import { defineConfig } from "vitest/config"; +import tsconfigPaths from "vite-tsconfig-paths"; + +export default defineConfig(({ mode }) => ({ + test: { + env: loadEnv(mode, process.cwd(), ""), + }, + plugins: [tsconfigPaths({ projects: ["."] })], +})); diff --git a/typescript/packages/legacy/coinbase-x402/.prettierignore b/typescript/packages/legacy/coinbase-x402/.prettierignore new file mode 100644 index 000000000..5bd240ba9 --- /dev/null +++ b/typescript/packages/legacy/coinbase-x402/.prettierignore @@ -0,0 +1,8 @@ +docs/ +dist/ +node_modules/ +coverage/ +.github/ +src/client +**/**/*.json +*.md \ No newline at end of file diff --git a/typescript/packages/legacy/coinbase-x402/.prettierrc b/typescript/packages/legacy/coinbase-x402/.prettierrc new file mode 100644 index 000000000..ffb416b74 --- /dev/null +++ b/typescript/packages/legacy/coinbase-x402/.prettierrc @@ -0,0 +1,11 @@ +{ + "tabWidth": 2, + "useTabs": false, + "semi": true, + "singleQuote": false, + "trailingComma": "all", + "bracketSpacing": true, + "arrowParens": "avoid", + "printWidth": 100, + "proseWrap": "never" +} diff --git a/typescript/packages/coinbase-x402/README.md b/typescript/packages/legacy/coinbase-x402/README.md similarity index 100% rename from typescript/packages/coinbase-x402/README.md rename to typescript/packages/legacy/coinbase-x402/README.md diff --git a/typescript/packages/x402-hono/eslint.config.js b/typescript/packages/legacy/coinbase-x402/eslint.config.js similarity index 100% rename from typescript/packages/x402-hono/eslint.config.js rename to typescript/packages/legacy/coinbase-x402/eslint.config.js diff --git a/typescript/packages/coinbase-x402/package.json b/typescript/packages/legacy/coinbase-x402/package.json similarity index 98% rename from typescript/packages/coinbase-x402/package.json rename to typescript/packages/legacy/coinbase-x402/package.json index 4ec39dd65..d906950f3 100644 --- a/typescript/packages/coinbase-x402/package.json +++ b/typescript/packages/legacy/coinbase-x402/package.json @@ -1,6 +1,6 @@ { "name": "@coinbase/x402", - "version": "0.7.0", + "version": "0.7.1", "main": "./dist/cjs/index.js", "module": "./dist/esm/index.js", "types": "./dist/index.d.ts", diff --git a/typescript/packages/coinbase-x402/scripts/postinstall.js b/typescript/packages/legacy/coinbase-x402/scripts/postinstall.js similarity index 100% rename from typescript/packages/coinbase-x402/scripts/postinstall.js rename to typescript/packages/legacy/coinbase-x402/scripts/postinstall.js diff --git a/typescript/packages/coinbase-x402/src/index.test.ts b/typescript/packages/legacy/coinbase-x402/src/index.test.ts similarity index 100% rename from typescript/packages/coinbase-x402/src/index.test.ts rename to typescript/packages/legacy/coinbase-x402/src/index.test.ts diff --git a/typescript/packages/coinbase-x402/src/index.ts b/typescript/packages/legacy/coinbase-x402/src/index.ts similarity index 99% rename from typescript/packages/coinbase-x402/src/index.ts rename to typescript/packages/legacy/coinbase-x402/src/index.ts index 1349d1b8e..55f31c86f 100644 --- a/typescript/packages/coinbase-x402/src/index.ts +++ b/typescript/packages/legacy/coinbase-x402/src/index.ts @@ -5,7 +5,7 @@ import { CreateHeaders } from "x402/verify"; const COINBASE_FACILITATOR_BASE_URL = "https://api.cdp.coinbase.com"; const COINBASE_FACILITATOR_V2_ROUTE = "/platform/v2/x402"; -const X402_SDK_VERSION = "0.7.0"; +const X402_SDK_VERSION = "0.7.1"; const CDP_SDK_VERSION = "1.29.0"; /** diff --git a/typescript/packages/legacy/coinbase-x402/tsconfig.json b/typescript/packages/legacy/coinbase-x402/tsconfig.json new file mode 100644 index 000000000..1b119d386 --- /dev/null +++ b/typescript/packages/legacy/coinbase-x402/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "allowJs": false, + "checkJs": false + }, + "include": ["src"] +} diff --git a/typescript/packages/x402-hono/tsup.config.ts b/typescript/packages/legacy/coinbase-x402/tsup.config.ts similarity index 100% rename from typescript/packages/x402-hono/tsup.config.ts rename to typescript/packages/legacy/coinbase-x402/tsup.config.ts diff --git a/typescript/packages/legacy/coinbase-x402/vitest.config.ts b/typescript/packages/legacy/coinbase-x402/vitest.config.ts new file mode 100644 index 000000000..156f8c924 --- /dev/null +++ b/typescript/packages/legacy/coinbase-x402/vitest.config.ts @@ -0,0 +1,10 @@ +import { loadEnv } from "vite"; +import { defineConfig } from "vitest/config"; +import tsconfigPaths from "vite-tsconfig-paths"; + +export default defineConfig(({ mode }) => ({ + test: { + env: loadEnv(mode, process.cwd(), ""), + }, + plugins: [tsconfigPaths({ projects: ["."] })], +})); diff --git a/typescript/packages/legacy/x402-axios/.prettierignore b/typescript/packages/legacy/x402-axios/.prettierignore new file mode 100644 index 000000000..5bd240ba9 --- /dev/null +++ b/typescript/packages/legacy/x402-axios/.prettierignore @@ -0,0 +1,8 @@ +docs/ +dist/ +node_modules/ +coverage/ +.github/ +src/client +**/**/*.json +*.md \ No newline at end of file diff --git a/typescript/packages/legacy/x402-axios/.prettierignore copy b/typescript/packages/legacy/x402-axios/.prettierignore copy new file mode 100644 index 000000000..5bd240ba9 --- /dev/null +++ b/typescript/packages/legacy/x402-axios/.prettierignore copy @@ -0,0 +1,8 @@ +docs/ +dist/ +node_modules/ +coverage/ +.github/ +src/client +**/**/*.json +*.md \ No newline at end of file diff --git a/typescript/packages/legacy/x402-axios/.prettierrc b/typescript/packages/legacy/x402-axios/.prettierrc new file mode 100644 index 000000000..ffb416b74 --- /dev/null +++ b/typescript/packages/legacy/x402-axios/.prettierrc @@ -0,0 +1,11 @@ +{ + "tabWidth": 2, + "useTabs": false, + "semi": true, + "singleQuote": false, + "trailingComma": "all", + "bracketSpacing": true, + "arrowParens": "avoid", + "printWidth": 100, + "proseWrap": "never" +} diff --git a/typescript/packages/x402-axios/README.md b/typescript/packages/legacy/x402-axios/README.md similarity index 100% rename from typescript/packages/x402-axios/README.md rename to typescript/packages/legacy/x402-axios/README.md diff --git a/typescript/packages/legacy/x402-axios/eslint.config.js b/typescript/packages/legacy/x402-axios/eslint.config.js new file mode 100644 index 000000000..ca28b5c47 --- /dev/null +++ b/typescript/packages/legacy/x402-axios/eslint.config.js @@ -0,0 +1,72 @@ +import js from "@eslint/js"; +import ts from "@typescript-eslint/eslint-plugin"; +import tsParser from "@typescript-eslint/parser"; +import prettier from "eslint-plugin-prettier"; +import jsdoc from "eslint-plugin-jsdoc"; +import importPlugin from "eslint-plugin-import"; + +export default [ + { + ignores: ["dist/**", "node_modules/**"], + }, + { + files: ["**/*.ts"], + languageOptions: { + parser: tsParser, + sourceType: "module", + ecmaVersion: 2020, + globals: { + process: "readonly", + __dirname: "readonly", + module: "readonly", + require: "readonly", + Buffer: "readonly", + exports: "readonly", + setTimeout: "readonly", + clearTimeout: "readonly", + setInterval: "readonly", + clearInterval: "readonly", + }, + }, + plugins: { + "@typescript-eslint": ts, + prettier: prettier, + jsdoc: jsdoc, + import: importPlugin, + }, + rules: { + ...ts.configs.recommended.rules, + "import/first": "error", + "prettier/prettier": "error", + "@typescript-eslint/member-ordering": "error", + "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_$" }], + "jsdoc/tag-lines": ["error", "any", { startLines: 1 }], + "jsdoc/check-alignment": "error", + "jsdoc/no-undefined-types": "off", + "jsdoc/check-param-names": "error", + "jsdoc/check-tag-names": "error", + "jsdoc/check-types": "error", + "jsdoc/implements-on-classes": "error", + "jsdoc/require-description": "error", + "jsdoc/require-jsdoc": [ + "error", + { + require: { + FunctionDeclaration: true, + MethodDefinition: true, + ClassDeclaration: true, + ArrowFunctionExpression: false, + FunctionExpression: false, + }, + }, + ], + "jsdoc/require-param": "error", + "jsdoc/require-param-description": "error", + "jsdoc/require-param-type": "off", + "jsdoc/require-returns": "error", + "jsdoc/require-returns-description": "error", + "jsdoc/require-returns-type": "off", + "jsdoc/require-hyphen-before-param-description": ["error", "always"], + }, + }, +]; diff --git a/typescript/packages/x402-axios/package.json b/typescript/packages/legacy/x402-axios/package.json similarity index 100% rename from typescript/packages/x402-axios/package.json rename to typescript/packages/legacy/x402-axios/package.json diff --git a/typescript/packages/x402-axios/src/index.test.ts b/typescript/packages/legacy/x402-axios/src/index.test.ts similarity index 100% rename from typescript/packages/x402-axios/src/index.test.ts rename to typescript/packages/legacy/x402-axios/src/index.test.ts diff --git a/typescript/packages/x402-axios/src/index.ts b/typescript/packages/legacy/x402-axios/src/index.ts similarity index 100% rename from typescript/packages/x402-axios/src/index.ts rename to typescript/packages/legacy/x402-axios/src/index.ts diff --git a/typescript/packages/legacy/x402-axios/tsconfig.json b/typescript/packages/legacy/x402-axios/tsconfig.json new file mode 100644 index 000000000..1b119d386 --- /dev/null +++ b/typescript/packages/legacy/x402-axios/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "allowJs": false, + "checkJs": false + }, + "include": ["src"] +} diff --git a/typescript/packages/legacy/x402-axios/tsup.config.ts b/typescript/packages/legacy/x402-axios/tsup.config.ts new file mode 100644 index 000000000..f8699f925 --- /dev/null +++ b/typescript/packages/legacy/x402-axios/tsup.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from "tsup"; + +const baseConfig = { + entry: { + index: "src/index.ts", + }, + dts: { + resolve: true, + }, + sourcemap: true, + target: "node16", +}; + +export default defineConfig([ + { + ...baseConfig, + format: "esm", + outDir: "dist/esm", + clean: true, + }, + { + ...baseConfig, + format: "cjs", + outDir: "dist/cjs", + clean: false, + }, +]); diff --git a/typescript/packages/legacy/x402-axios/vitest.config.ts b/typescript/packages/legacy/x402-axios/vitest.config.ts new file mode 100644 index 000000000..156f8c924 --- /dev/null +++ b/typescript/packages/legacy/x402-axios/vitest.config.ts @@ -0,0 +1,10 @@ +import { loadEnv } from "vite"; +import { defineConfig } from "vitest/config"; +import tsconfigPaths from "vite-tsconfig-paths"; + +export default defineConfig(({ mode }) => ({ + test: { + env: loadEnv(mode, process.cwd(), ""), + }, + plugins: [tsconfigPaths({ projects: ["."] })], +})); diff --git a/typescript/packages/legacy/x402-express/.prettierignore b/typescript/packages/legacy/x402-express/.prettierignore new file mode 100644 index 000000000..5bd240ba9 --- /dev/null +++ b/typescript/packages/legacy/x402-express/.prettierignore @@ -0,0 +1,8 @@ +docs/ +dist/ +node_modules/ +coverage/ +.github/ +src/client +**/**/*.json +*.md \ No newline at end of file diff --git a/typescript/packages/legacy/x402-express/.prettierrc b/typescript/packages/legacy/x402-express/.prettierrc new file mode 100644 index 000000000..ffb416b74 --- /dev/null +++ b/typescript/packages/legacy/x402-express/.prettierrc @@ -0,0 +1,11 @@ +{ + "tabWidth": 2, + "useTabs": false, + "semi": true, + "singleQuote": false, + "trailingComma": "all", + "bracketSpacing": true, + "arrowParens": "avoid", + "printWidth": 100, + "proseWrap": "never" +} diff --git a/typescript/packages/x402-express/README.md b/typescript/packages/legacy/x402-express/README.md similarity index 100% rename from typescript/packages/x402-express/README.md rename to typescript/packages/legacy/x402-express/README.md diff --git a/typescript/packages/legacy/x402-express/eslint.config.js b/typescript/packages/legacy/x402-express/eslint.config.js new file mode 100644 index 000000000..044411cb5 --- /dev/null +++ b/typescript/packages/legacy/x402-express/eslint.config.js @@ -0,0 +1,73 @@ +import js from "@eslint/js"; +import ts from "@typescript-eslint/eslint-plugin"; +import tsParser from "@typescript-eslint/parser"; +import prettier from "eslint-plugin-prettier"; +import jsdoc from "eslint-plugin-jsdoc"; +import importPlugin from "eslint-plugin-import"; + +export default [ + { + ignores: ["dist/**", "node_modules/**"], + }, + { + files: ["**/*.ts"], + languageOptions: { + parser: tsParser, + sourceType: "module", + ecmaVersion: 2020, + globals: { + process: "readonly", + __dirname: "readonly", + module: "readonly", + require: "readonly", + Buffer: "readonly", + BufferEncoding: "readonly", + exports: "readonly", + setTimeout: "readonly", + clearTimeout: "readonly", + setInterval: "readonly", + clearInterval: "readonly", + }, + }, + plugins: { + "@typescript-eslint": ts, + prettier: prettier, + jsdoc: jsdoc, + import: importPlugin, + }, + rules: { + ...ts.configs.recommended.rules, + "import/first": "error", + "prettier/prettier": "error", + "@typescript-eslint/member-ordering": "error", + "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_$" }], + "jsdoc/tag-lines": ["error", "any", { startLines: 1 }], + "jsdoc/check-alignment": "error", + "jsdoc/no-undefined-types": "off", + "jsdoc/check-param-names": "error", + "jsdoc/check-tag-names": "error", + "jsdoc/check-types": "error", + "jsdoc/implements-on-classes": "error", + "jsdoc/require-description": "error", + "jsdoc/require-jsdoc": [ + "error", + { + require: { + FunctionDeclaration: true, + MethodDefinition: true, + ClassDeclaration: true, + ArrowFunctionExpression: false, + FunctionExpression: false, + }, + }, + ], + "jsdoc/require-param": "error", + "jsdoc/require-param-description": "error", + "jsdoc/require-param-type": "off", + "jsdoc/require-returns": "error", + "jsdoc/require-returns-description": "error", + "jsdoc/require-returns-type": "off", + "jsdoc/require-hyphen-before-param-description": ["error", "always"], + }, + }, +]; diff --git a/typescript/packages/x402-express/package.json b/typescript/packages/legacy/x402-express/package.json similarity index 98% rename from typescript/packages/x402-express/package.json rename to typescript/packages/legacy/x402-express/package.json index cd8ebe6d3..3fcd5542a 100644 --- a/typescript/packages/x402-express/package.json +++ b/typescript/packages/legacy/x402-express/package.json @@ -1,6 +1,6 @@ { "name": "x402-express", - "version": "0.7.0", + "version": "0.7.1", "main": "./dist/cjs/index.js", "module": "./dist/esm/index.js", "types": "./dist/index.d.ts", diff --git a/typescript/packages/x402-express/src/index.test.ts b/typescript/packages/legacy/x402-express/src/index.test.ts similarity index 100% rename from typescript/packages/x402-express/src/index.test.ts rename to typescript/packages/legacy/x402-express/src/index.test.ts diff --git a/typescript/packages/x402-express/src/index.ts b/typescript/packages/legacy/x402-express/src/index.ts similarity index 100% rename from typescript/packages/x402-express/src/index.ts rename to typescript/packages/legacy/x402-express/src/index.ts diff --git a/typescript/packages/x402-express/src/session-token.test.ts b/typescript/packages/legacy/x402-express/src/session-token.test.ts similarity index 100% rename from typescript/packages/x402-express/src/session-token.test.ts rename to typescript/packages/legacy/x402-express/src/session-token.test.ts diff --git a/typescript/packages/x402-express/src/session-token.ts b/typescript/packages/legacy/x402-express/src/session-token.ts similarity index 100% rename from typescript/packages/x402-express/src/session-token.ts rename to typescript/packages/legacy/x402-express/src/session-token.ts diff --git a/typescript/packages/legacy/x402-express/tsconfig.json b/typescript/packages/legacy/x402-express/tsconfig.json new file mode 100644 index 000000000..1b119d386 --- /dev/null +++ b/typescript/packages/legacy/x402-express/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "allowJs": false, + "checkJs": false + }, + "include": ["src"] +} diff --git a/typescript/packages/legacy/x402-express/tsup.config.ts b/typescript/packages/legacy/x402-express/tsup.config.ts new file mode 100644 index 000000000..f8699f925 --- /dev/null +++ b/typescript/packages/legacy/x402-express/tsup.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from "tsup"; + +const baseConfig = { + entry: { + index: "src/index.ts", + }, + dts: { + resolve: true, + }, + sourcemap: true, + target: "node16", +}; + +export default defineConfig([ + { + ...baseConfig, + format: "esm", + outDir: "dist/esm", + clean: true, + }, + { + ...baseConfig, + format: "cjs", + outDir: "dist/cjs", + clean: false, + }, +]); diff --git a/typescript/packages/legacy/x402-express/vitest.config.ts b/typescript/packages/legacy/x402-express/vitest.config.ts new file mode 100644 index 000000000..156f8c924 --- /dev/null +++ b/typescript/packages/legacy/x402-express/vitest.config.ts @@ -0,0 +1,10 @@ +import { loadEnv } from "vite"; +import { defineConfig } from "vitest/config"; +import tsconfigPaths from "vite-tsconfig-paths"; + +export default defineConfig(({ mode }) => ({ + test: { + env: loadEnv(mode, process.cwd(), ""), + }, + plugins: [tsconfigPaths({ projects: ["."] })], +})); diff --git a/typescript/packages/legacy/x402-fetch/.prettierignore b/typescript/packages/legacy/x402-fetch/.prettierignore new file mode 100644 index 000000000..5bd240ba9 --- /dev/null +++ b/typescript/packages/legacy/x402-fetch/.prettierignore @@ -0,0 +1,8 @@ +docs/ +dist/ +node_modules/ +coverage/ +.github/ +src/client +**/**/*.json +*.md \ No newline at end of file diff --git a/typescript/packages/legacy/x402-fetch/.prettierrc b/typescript/packages/legacy/x402-fetch/.prettierrc new file mode 100644 index 000000000..ffb416b74 --- /dev/null +++ b/typescript/packages/legacy/x402-fetch/.prettierrc @@ -0,0 +1,11 @@ +{ + "tabWidth": 2, + "useTabs": false, + "semi": true, + "singleQuote": false, + "trailingComma": "all", + "bracketSpacing": true, + "arrowParens": "avoid", + "printWidth": 100, + "proseWrap": "never" +} diff --git a/typescript/packages/x402-fetch/README.md b/typescript/packages/legacy/x402-fetch/README.md similarity index 100% rename from typescript/packages/x402-fetch/README.md rename to typescript/packages/legacy/x402-fetch/README.md diff --git a/typescript/packages/legacy/x402-fetch/eslint.config.js b/typescript/packages/legacy/x402-fetch/eslint.config.js new file mode 100644 index 000000000..7b03c4227 --- /dev/null +++ b/typescript/packages/legacy/x402-fetch/eslint.config.js @@ -0,0 +1,76 @@ +import js from "@eslint/js"; +import ts from "@typescript-eslint/eslint-plugin"; +import tsParser from "@typescript-eslint/parser"; +import prettier from "eslint-plugin-prettier"; +import jsdoc from "eslint-plugin-jsdoc"; +import importPlugin from "eslint-plugin-import"; + +export default [ + { + ignores: ["dist/**", "node_modules/**"], + }, + { + files: ["**/*.ts"], + languageOptions: { + parser: tsParser, + sourceType: "module", + ecmaVersion: 2020, + globals: { + process: "readonly", + __dirname: "readonly", + module: "readonly", + require: "readonly", + Buffer: "readonly", + RequestInfo: "readonly", + RequestInit: "readonly", + Response: "readonly", + Headers: "readonly", + exports: "readonly", + setTimeout: "readonly", + clearTimeout: "readonly", + setInterval: "readonly", + clearInterval: "readonly", + }, + }, + plugins: { + "@typescript-eslint": ts, + prettier: prettier, + jsdoc: jsdoc, + import: importPlugin, + }, + rules: { + ...ts.configs.recommended.rules, + "import/first": "error", + "prettier/prettier": "error", + "@typescript-eslint/member-ordering": "error", + "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_$" }], + "jsdoc/tag-lines": ["error", "any", { startLines: 1 }], + "jsdoc/check-alignment": "error", + "jsdoc/no-undefined-types": "off", + "jsdoc/check-param-names": "error", + "jsdoc/check-tag-names": "error", + "jsdoc/check-types": "error", + "jsdoc/implements-on-classes": "error", + "jsdoc/require-description": "error", + "jsdoc/require-jsdoc": [ + "error", + { + require: { + FunctionDeclaration: true, + MethodDefinition: true, + ClassDeclaration: true, + ArrowFunctionExpression: false, + FunctionExpression: false, + }, + }, + ], + "jsdoc/require-param": "error", + "jsdoc/require-param-description": "error", + "jsdoc/require-param-type": "off", + "jsdoc/require-returns": "error", + "jsdoc/require-returns-description": "error", + "jsdoc/require-returns-type": "off", + "jsdoc/require-hyphen-before-param-description": ["error", "always"], + }, + }, +]; diff --git a/typescript/packages/x402-fetch/package.json b/typescript/packages/legacy/x402-fetch/package.json similarity index 100% rename from typescript/packages/x402-fetch/package.json rename to typescript/packages/legacy/x402-fetch/package.json diff --git a/typescript/packages/x402-fetch/src/index.test.ts b/typescript/packages/legacy/x402-fetch/src/index.test.ts similarity index 100% rename from typescript/packages/x402-fetch/src/index.test.ts rename to typescript/packages/legacy/x402-fetch/src/index.test.ts diff --git a/typescript/packages/x402-fetch/src/index.ts b/typescript/packages/legacy/x402-fetch/src/index.ts similarity index 100% rename from typescript/packages/x402-fetch/src/index.ts rename to typescript/packages/legacy/x402-fetch/src/index.ts diff --git a/typescript/packages/legacy/x402-fetch/tsconfig.json b/typescript/packages/legacy/x402-fetch/tsconfig.json new file mode 100644 index 000000000..117765590 --- /dev/null +++ b/typescript/packages/legacy/x402-fetch/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "allowJs": false, + "checkJs": false, + "lib": ["DOM"] + }, + "include": ["src"] +} diff --git a/typescript/packages/legacy/x402-fetch/tsup.config.ts b/typescript/packages/legacy/x402-fetch/tsup.config.ts new file mode 100644 index 000000000..f8699f925 --- /dev/null +++ b/typescript/packages/legacy/x402-fetch/tsup.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from "tsup"; + +const baseConfig = { + entry: { + index: "src/index.ts", + }, + dts: { + resolve: true, + }, + sourcemap: true, + target: "node16", +}; + +export default defineConfig([ + { + ...baseConfig, + format: "esm", + outDir: "dist/esm", + clean: true, + }, + { + ...baseConfig, + format: "cjs", + outDir: "dist/cjs", + clean: false, + }, +]); diff --git a/typescript/packages/legacy/x402-fetch/vitest.config.ts b/typescript/packages/legacy/x402-fetch/vitest.config.ts new file mode 100644 index 000000000..156f8c924 --- /dev/null +++ b/typescript/packages/legacy/x402-fetch/vitest.config.ts @@ -0,0 +1,10 @@ +import { loadEnv } from "vite"; +import { defineConfig } from "vitest/config"; +import tsconfigPaths from "vite-tsconfig-paths"; + +export default defineConfig(({ mode }) => ({ + test: { + env: loadEnv(mode, process.cwd(), ""), + }, + plugins: [tsconfigPaths({ projects: ["."] })], +})); diff --git a/typescript/packages/legacy/x402-hono/.prettierignore b/typescript/packages/legacy/x402-hono/.prettierignore new file mode 100644 index 000000000..5bd240ba9 --- /dev/null +++ b/typescript/packages/legacy/x402-hono/.prettierignore @@ -0,0 +1,8 @@ +docs/ +dist/ +node_modules/ +coverage/ +.github/ +src/client +**/**/*.json +*.md \ No newline at end of file diff --git a/typescript/packages/legacy/x402-hono/.prettierrc b/typescript/packages/legacy/x402-hono/.prettierrc new file mode 100644 index 000000000..ffb416b74 --- /dev/null +++ b/typescript/packages/legacy/x402-hono/.prettierrc @@ -0,0 +1,11 @@ +{ + "tabWidth": 2, + "useTabs": false, + "semi": true, + "singleQuote": false, + "trailingComma": "all", + "bracketSpacing": true, + "arrowParens": "avoid", + "printWidth": 100, + "proseWrap": "never" +} diff --git a/typescript/packages/x402-hono/README.md b/typescript/packages/legacy/x402-hono/README.md similarity index 100% rename from typescript/packages/x402-hono/README.md rename to typescript/packages/legacy/x402-hono/README.md diff --git a/typescript/packages/legacy/x402-hono/eslint.config.js b/typescript/packages/legacy/x402-hono/eslint.config.js new file mode 100644 index 000000000..28e564722 --- /dev/null +++ b/typescript/packages/legacy/x402-hono/eslint.config.js @@ -0,0 +1,73 @@ +import js from "@eslint/js"; +import ts from "@typescript-eslint/eslint-plugin"; +import tsParser from "@typescript-eslint/parser"; +import prettier from "eslint-plugin-prettier"; +import jsdoc from "eslint-plugin-jsdoc"; +import importPlugin from "eslint-plugin-import"; + +export default [ + { + ignores: ["dist/**", "node_modules/**"], + }, + { + files: ["**/*.ts"], + languageOptions: { + parser: tsParser, + sourceType: "module", + ecmaVersion: 2020, + globals: { + process: "readonly", + __dirname: "readonly", + module: "readonly", + require: "readonly", + Buffer: "readonly", + Headers: "readonly", + exports: "readonly", + setTimeout: "readonly", + clearTimeout: "readonly", + setInterval: "readonly", + clearInterval: "readonly", + }, + }, + plugins: { + "@typescript-eslint": ts, + prettier: prettier, + jsdoc: jsdoc, + import: importPlugin, + }, + rules: { + ...ts.configs.recommended.rules, + "import/first": "error", + "prettier/prettier": "error", + "@typescript-eslint/member-ordering": "error", + "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_$" }], + "jsdoc/tag-lines": ["error", "any", { startLines: 1 }], + "jsdoc/check-alignment": "error", + "jsdoc/no-undefined-types": "off", + "jsdoc/check-param-names": "error", + "jsdoc/check-tag-names": "error", + "jsdoc/check-types": "error", + "jsdoc/implements-on-classes": "error", + "jsdoc/require-description": "error", + "jsdoc/require-jsdoc": [ + "error", + { + require: { + FunctionDeclaration: true, + MethodDefinition: true, + ClassDeclaration: true, + ArrowFunctionExpression: false, + FunctionExpression: false, + }, + }, + ], + "jsdoc/require-param": "error", + "jsdoc/require-param-description": "error", + "jsdoc/require-param-type": "off", + "jsdoc/require-returns": "error", + "jsdoc/require-returns-description": "error", + "jsdoc/require-returns-type": "off", + "jsdoc/require-hyphen-before-param-description": ["error", "always"], + }, + }, +]; diff --git a/typescript/packages/x402-hono/package.json b/typescript/packages/legacy/x402-hono/package.json similarity index 98% rename from typescript/packages/x402-hono/package.json rename to typescript/packages/legacy/x402-hono/package.json index 2f24aec7d..cf497dce0 100644 --- a/typescript/packages/x402-hono/package.json +++ b/typescript/packages/legacy/x402-hono/package.json @@ -1,6 +1,6 @@ { "name": "x402-hono", - "version": "0.7.0", + "version": "0.7.1", "main": "./dist/cjs/index.js", "module": "./dist/esm/index.js", "types": "./dist/index.d.ts", diff --git a/typescript/packages/x402-hono/src/index.test.ts b/typescript/packages/legacy/x402-hono/src/index.test.ts similarity index 100% rename from typescript/packages/x402-hono/src/index.test.ts rename to typescript/packages/legacy/x402-hono/src/index.test.ts diff --git a/typescript/packages/x402-hono/src/index.ts b/typescript/packages/legacy/x402-hono/src/index.ts similarity index 100% rename from typescript/packages/x402-hono/src/index.ts rename to typescript/packages/legacy/x402-hono/src/index.ts diff --git a/typescript/packages/x402-hono/src/session-token.test.ts b/typescript/packages/legacy/x402-hono/src/session-token.test.ts similarity index 100% rename from typescript/packages/x402-hono/src/session-token.test.ts rename to typescript/packages/legacy/x402-hono/src/session-token.test.ts diff --git a/typescript/packages/x402-hono/src/session-token.ts b/typescript/packages/legacy/x402-hono/src/session-token.ts similarity index 100% rename from typescript/packages/x402-hono/src/session-token.ts rename to typescript/packages/legacy/x402-hono/src/session-token.ts diff --git a/typescript/packages/legacy/x402-hono/tsconfig.json b/typescript/packages/legacy/x402-hono/tsconfig.json new file mode 100644 index 000000000..1b119d386 --- /dev/null +++ b/typescript/packages/legacy/x402-hono/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "allowJs": false, + "checkJs": false + }, + "include": ["src"] +} diff --git a/typescript/packages/legacy/x402-hono/tsup.config.ts b/typescript/packages/legacy/x402-hono/tsup.config.ts new file mode 100644 index 000000000..f8699f925 --- /dev/null +++ b/typescript/packages/legacy/x402-hono/tsup.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from "tsup"; + +const baseConfig = { + entry: { + index: "src/index.ts", + }, + dts: { + resolve: true, + }, + sourcemap: true, + target: "node16", +}; + +export default defineConfig([ + { + ...baseConfig, + format: "esm", + outDir: "dist/esm", + clean: true, + }, + { + ...baseConfig, + format: "cjs", + outDir: "dist/cjs", + clean: false, + }, +]); diff --git a/typescript/packages/legacy/x402-hono/vitest.config.ts b/typescript/packages/legacy/x402-hono/vitest.config.ts new file mode 100644 index 000000000..156f8c924 --- /dev/null +++ b/typescript/packages/legacy/x402-hono/vitest.config.ts @@ -0,0 +1,10 @@ +import { loadEnv } from "vite"; +import { defineConfig } from "vitest/config"; +import tsconfigPaths from "vite-tsconfig-paths"; + +export default defineConfig(({ mode }) => ({ + test: { + env: loadEnv(mode, process.cwd(), ""), + }, + plugins: [tsconfigPaths({ projects: ["."] })], +})); diff --git a/typescript/packages/legacy/x402-next/.prettierignore b/typescript/packages/legacy/x402-next/.prettierignore new file mode 100644 index 000000000..5bd240ba9 --- /dev/null +++ b/typescript/packages/legacy/x402-next/.prettierignore @@ -0,0 +1,8 @@ +docs/ +dist/ +node_modules/ +coverage/ +.github/ +src/client +**/**/*.json +*.md \ No newline at end of file diff --git a/typescript/packages/legacy/x402-next/.prettierrc b/typescript/packages/legacy/x402-next/.prettierrc new file mode 100644 index 000000000..ffb416b74 --- /dev/null +++ b/typescript/packages/legacy/x402-next/.prettierrc @@ -0,0 +1,11 @@ +{ + "tabWidth": 2, + "useTabs": false, + "semi": true, + "singleQuote": false, + "trailingComma": "all", + "bracketSpacing": true, + "arrowParens": "avoid", + "printWidth": 100, + "proseWrap": "never" +} diff --git a/typescript/packages/x402-next/README.md b/typescript/packages/legacy/x402-next/README.md similarity index 100% rename from typescript/packages/x402-next/README.md rename to typescript/packages/legacy/x402-next/README.md diff --git a/typescript/packages/legacy/x402-next/eslint.config.js b/typescript/packages/legacy/x402-next/eslint.config.js new file mode 100644 index 000000000..ca28b5c47 --- /dev/null +++ b/typescript/packages/legacy/x402-next/eslint.config.js @@ -0,0 +1,72 @@ +import js from "@eslint/js"; +import ts from "@typescript-eslint/eslint-plugin"; +import tsParser from "@typescript-eslint/parser"; +import prettier from "eslint-plugin-prettier"; +import jsdoc from "eslint-plugin-jsdoc"; +import importPlugin from "eslint-plugin-import"; + +export default [ + { + ignores: ["dist/**", "node_modules/**"], + }, + { + files: ["**/*.ts"], + languageOptions: { + parser: tsParser, + sourceType: "module", + ecmaVersion: 2020, + globals: { + process: "readonly", + __dirname: "readonly", + module: "readonly", + require: "readonly", + Buffer: "readonly", + exports: "readonly", + setTimeout: "readonly", + clearTimeout: "readonly", + setInterval: "readonly", + clearInterval: "readonly", + }, + }, + plugins: { + "@typescript-eslint": ts, + prettier: prettier, + jsdoc: jsdoc, + import: importPlugin, + }, + rules: { + ...ts.configs.recommended.rules, + "import/first": "error", + "prettier/prettier": "error", + "@typescript-eslint/member-ordering": "error", + "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_$" }], + "jsdoc/tag-lines": ["error", "any", { startLines: 1 }], + "jsdoc/check-alignment": "error", + "jsdoc/no-undefined-types": "off", + "jsdoc/check-param-names": "error", + "jsdoc/check-tag-names": "error", + "jsdoc/check-types": "error", + "jsdoc/implements-on-classes": "error", + "jsdoc/require-description": "error", + "jsdoc/require-jsdoc": [ + "error", + { + require: { + FunctionDeclaration: true, + MethodDefinition: true, + ClassDeclaration: true, + ArrowFunctionExpression: false, + FunctionExpression: false, + }, + }, + ], + "jsdoc/require-param": "error", + "jsdoc/require-param-description": "error", + "jsdoc/require-param-type": "off", + "jsdoc/require-returns": "error", + "jsdoc/require-returns-description": "error", + "jsdoc/require-returns-type": "off", + "jsdoc/require-hyphen-before-param-description": ["error", "always"], + }, + }, +]; diff --git a/typescript/packages/x402-next/package.json b/typescript/packages/legacy/x402-next/package.json similarity index 98% rename from typescript/packages/x402-next/package.json rename to typescript/packages/legacy/x402-next/package.json index a636d7659..ed58f0bc9 100644 --- a/typescript/packages/x402-next/package.json +++ b/typescript/packages/legacy/x402-next/package.json @@ -1,6 +1,6 @@ { "name": "x402-next", - "version": "0.7.0", + "version": "0.7.1", "main": "./dist/cjs/index.js", "module": "./dist/esm/index.js", "types": "./dist/index.d.ts", diff --git a/typescript/packages/x402-next/src/api/session-token.test.ts b/typescript/packages/legacy/x402-next/src/api/session-token.test.ts similarity index 100% rename from typescript/packages/x402-next/src/api/session-token.test.ts rename to typescript/packages/legacy/x402-next/src/api/session-token.test.ts diff --git a/typescript/packages/x402-next/src/api/session-token.ts b/typescript/packages/legacy/x402-next/src/api/session-token.ts similarity index 100% rename from typescript/packages/x402-next/src/api/session-token.ts rename to typescript/packages/legacy/x402-next/src/api/session-token.ts diff --git a/typescript/packages/x402-next/src/index.test.ts b/typescript/packages/legacy/x402-next/src/index.test.ts similarity index 100% rename from typescript/packages/x402-next/src/index.test.ts rename to typescript/packages/legacy/x402-next/src/index.test.ts diff --git a/typescript/packages/x402-next/src/index.ts b/typescript/packages/legacy/x402-next/src/index.ts similarity index 100% rename from typescript/packages/x402-next/src/index.ts rename to typescript/packages/legacy/x402-next/src/index.ts diff --git a/typescript/packages/legacy/x402-next/tsconfig.json b/typescript/packages/legacy/x402-next/tsconfig.json new file mode 100644 index 000000000..1b119d386 --- /dev/null +++ b/typescript/packages/legacy/x402-next/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "allowJs": false, + "checkJs": false + }, + "include": ["src"] +} diff --git a/typescript/packages/legacy/x402-next/tsup.config.ts b/typescript/packages/legacy/x402-next/tsup.config.ts new file mode 100644 index 000000000..7ac9e3a6b --- /dev/null +++ b/typescript/packages/legacy/x402-next/tsup.config.ts @@ -0,0 +1,28 @@ +import { defineConfig } from "tsup"; + +const baseConfig = { + entry: { + index: "src/index.ts", + }, + dts: { + resolve: true, + }, + sourcemap: true, + target: "node16", + external: ["next"], +}; + +export default defineConfig([ + { + ...baseConfig, + format: "esm", + outDir: "dist/esm", + clean: true, + }, + { + ...baseConfig, + format: "cjs", + outDir: "dist/cjs", + clean: false, + }, +]); diff --git a/typescript/packages/legacy/x402-next/vitest.config.ts b/typescript/packages/legacy/x402-next/vitest.config.ts new file mode 100644 index 000000000..156f8c924 --- /dev/null +++ b/typescript/packages/legacy/x402-next/vitest.config.ts @@ -0,0 +1,10 @@ +import { loadEnv } from "vite"; +import { defineConfig } from "vitest/config"; +import tsconfigPaths from "vite-tsconfig-paths"; + +export default defineConfig(({ mode }) => ({ + test: { + env: loadEnv(mode, process.cwd(), ""), + }, + plugins: [tsconfigPaths({ projects: ["."] })], +})); diff --git a/typescript/packages/legacy/x402/.ci-touch b/typescript/packages/legacy/x402/.ci-touch new file mode 100644 index 000000000..0202f4566 --- /dev/null +++ b/typescript/packages/legacy/x402/.ci-touch @@ -0,0 +1 @@ +2025-10-28T16:27:30-0400 diff --git a/typescript/packages/legacy/x402/.prettierignore b/typescript/packages/legacy/x402/.prettierignore new file mode 100644 index 000000000..5bd240ba9 --- /dev/null +++ b/typescript/packages/legacy/x402/.prettierignore @@ -0,0 +1,8 @@ +docs/ +dist/ +node_modules/ +coverage/ +.github/ +src/client +**/**/*.json +*.md \ No newline at end of file diff --git a/typescript/packages/legacy/x402/.prettierrc b/typescript/packages/legacy/x402/.prettierrc new file mode 100644 index 000000000..ffb416b74 --- /dev/null +++ b/typescript/packages/legacy/x402/.prettierrc @@ -0,0 +1,11 @@ +{ + "tabWidth": 2, + "useTabs": false, + "semi": true, + "singleQuote": false, + "trailingComma": "all", + "bracketSpacing": true, + "arrowParens": "avoid", + "printWidth": 100, + "proseWrap": "never" +} diff --git a/typescript/packages/x402/README.md b/typescript/packages/legacy/x402/README.md similarity index 100% rename from typescript/packages/x402/README.md rename to typescript/packages/legacy/x402/README.md diff --git a/typescript/packages/legacy/x402/eslint.config.js b/typescript/packages/legacy/x402/eslint.config.js new file mode 100644 index 000000000..687c7ffdb --- /dev/null +++ b/typescript/packages/legacy/x402/eslint.config.js @@ -0,0 +1,72 @@ +import js from "@eslint/js"; +import ts from "@typescript-eslint/eslint-plugin"; +import tsParser from "@typescript-eslint/parser"; +import prettier from "eslint-plugin-prettier"; +import jsdoc from "eslint-plugin-jsdoc"; +import importPlugin from "eslint-plugin-import"; + +export default [ + { + ignores: ["dist/**", "node_modules/**", "src/paywall/dist/**", "src/paywall/gen/**"], + }, + { + files: ["**/*.ts", "**/*.tsx"], + languageOptions: { + parser: tsParser, + sourceType: "module", + ecmaVersion: 2020, + globals: { + process: "readonly", + __dirname: "readonly", + module: "readonly", + require: "readonly", + Buffer: "readonly", + exports: "readonly", + setTimeout: "readonly", + clearTimeout: "readonly", + setInterval: "readonly", + clearInterval: "readonly", + }, + }, + plugins: { + "@typescript-eslint": ts, + prettier: prettier, + jsdoc: jsdoc, + import: importPlugin, + }, + rules: { + ...ts.configs.recommended.rules, + "import/first": "error", + "prettier/prettier": "error", + "@typescript-eslint/member-ordering": "error", + "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_$" }], + "jsdoc/tag-lines": ["error", "any", { startLines: 1 }], + "jsdoc/check-alignment": "error", + "jsdoc/no-undefined-types": "off", + "jsdoc/check-param-names": "error", + "jsdoc/check-tag-names": "error", + "jsdoc/check-types": "error", + "jsdoc/implements-on-classes": "error", + "jsdoc/require-description": "error", + "jsdoc/require-jsdoc": [ + "error", + { + require: { + FunctionDeclaration: true, + MethodDefinition: true, + ClassDeclaration: true, + ArrowFunctionExpression: false, + FunctionExpression: false, + }, + }, + ], + "jsdoc/require-param": "error", + "jsdoc/require-param-description": "error", + "jsdoc/require-param-type": "off", + "jsdoc/require-returns": "error", + "jsdoc/require-returns-description": "error", + "jsdoc/require-returns-type": "off", + "jsdoc/require-hyphen-before-param-description": ["error", "always"], + }, + }, +]; diff --git a/typescript/packages/x402/package.json b/typescript/packages/legacy/x402/package.json similarity index 95% rename from typescript/packages/x402/package.json rename to typescript/packages/legacy/x402/package.json index 2a13c1451..b24239025 100644 --- a/typescript/packages/x402/package.json +++ b/typescript/packages/legacy/x402/package.json @@ -1,6 +1,6 @@ { "name": "x402", - "version": "0.7.0", + "version": "0.7.1", "main": "./dist/cjs/index.js", "module": "./dist/esm/index.js", "types": "./dist/cjs/index.d.ts", @@ -56,6 +56,10 @@ "@solana-program/token-2022": "^0.4.2", "@solana/kit": "^2.1.1", "@solana/transaction-confirmation": "^2.1.1", + "@solana/wallet-standard-features": "^1.3.0", + "@wallet-standard/app": "^1.1.0", + "@wallet-standard/base": "^1.1.0", + "@wallet-standard/features": "^1.1.0", "viem": "^2.21.26", "wagmi": "^2.15.6", "zod": "^3.24.2" diff --git a/typescript/packages/x402/src/client/createPaymentHeader.test.ts b/typescript/packages/legacy/x402/src/client/createPaymentHeader.test.ts similarity index 100% rename from typescript/packages/x402/src/client/createPaymentHeader.test.ts rename to typescript/packages/legacy/x402/src/client/createPaymentHeader.test.ts diff --git a/typescript/packages/x402/src/client/createPaymentHeader.ts b/typescript/packages/legacy/x402/src/client/createPaymentHeader.ts similarity index 100% rename from typescript/packages/x402/src/client/createPaymentHeader.ts rename to typescript/packages/legacy/x402/src/client/createPaymentHeader.ts diff --git a/typescript/packages/x402/src/client/index.ts b/typescript/packages/legacy/x402/src/client/index.ts similarity index 100% rename from typescript/packages/x402/src/client/index.ts rename to typescript/packages/legacy/x402/src/client/index.ts diff --git a/typescript/packages/x402/src/client/preparePaymentHeader.ts b/typescript/packages/legacy/x402/src/client/preparePaymentHeader.ts similarity index 100% rename from typescript/packages/x402/src/client/preparePaymentHeader.ts rename to typescript/packages/legacy/x402/src/client/preparePaymentHeader.ts diff --git a/typescript/packages/x402/src/client/selectPaymentRequirements.test.ts b/typescript/packages/legacy/x402/src/client/selectPaymentRequirements.test.ts similarity index 100% rename from typescript/packages/x402/src/client/selectPaymentRequirements.test.ts rename to typescript/packages/legacy/x402/src/client/selectPaymentRequirements.test.ts diff --git a/typescript/packages/x402/src/client/selectPaymentRequirements.ts b/typescript/packages/legacy/x402/src/client/selectPaymentRequirements.ts similarity index 100% rename from typescript/packages/x402/src/client/selectPaymentRequirements.ts rename to typescript/packages/legacy/x402/src/client/selectPaymentRequirements.ts diff --git a/typescript/packages/x402/src/client/signPaymentHeader.ts b/typescript/packages/legacy/x402/src/client/signPaymentHeader.ts similarity index 100% rename from typescript/packages/x402/src/client/signPaymentHeader.ts rename to typescript/packages/legacy/x402/src/client/signPaymentHeader.ts diff --git a/typescript/packages/x402/src/facilitator/facilitator.ts b/typescript/packages/legacy/x402/src/facilitator/facilitator.ts similarity index 100% rename from typescript/packages/x402/src/facilitator/facilitator.ts rename to typescript/packages/legacy/x402/src/facilitator/facilitator.ts diff --git a/typescript/packages/x402/src/facilitator/index.ts b/typescript/packages/legacy/x402/src/facilitator/index.ts similarity index 100% rename from typescript/packages/x402/src/facilitator/index.ts rename to typescript/packages/legacy/x402/src/facilitator/index.ts diff --git a/typescript/packages/x402/src/index.ts b/typescript/packages/legacy/x402/src/index.ts similarity index 100% rename from typescript/packages/x402/src/index.ts rename to typescript/packages/legacy/x402/src/index.ts diff --git a/typescript/packages/x402/src/paywall/README.md b/typescript/packages/legacy/x402/src/paywall/README.md similarity index 62% rename from typescript/packages/x402/src/paywall/README.md rename to typescript/packages/legacy/x402/src/paywall/README.md index da29df1f7..a4f6ee674 100644 --- a/typescript/packages/x402/src/paywall/README.md +++ b/typescript/packages/legacy/x402/src/paywall/README.md @@ -18,7 +18,9 @@ export const middleware = paymentMiddleware( ## Features -**Wallet Connection & Payment Processing:** Supports Coinbase Smart Wallet, Coinbase EOA, MetaMask, Phantom, Rabby, Trust Wallet, and Frame. Includes x402 payment processing by default. +**Wallet Connection & Payment Processing:** Supports Coinbase Smart Wallet, Coinbase EOA, MetaMask, Rabby, Trust Wallet, Frame, and wallet-standard compatible Solana wallets such as Phantom and Backpack. Includes x402 payment processing by default. + +**Multi-chain Aware:** Automatically chooses the best available payment requirement (Base, Base Sepolia, Solana, Solana Devnet) and renders the appropriate wallet flow without additional configuration. **Enhanced RPC** (optional): Add `cdpClientKey` to use Coinbase's hosted RPC infrastructure for improved performance. @@ -36,3 +38,9 @@ export const middleware = paymentMiddleware( The paywall automatically loads when a browser attempts to access a protected route configured in your middleware. ![](../../../../../static/paywall.jpg) + +### Solana Support + +- Solana flows use the [Wallet Standard](https://solana.com/developers/wallets/wallet-standard) to discover installed wallets at runtime. +- The paywall requests `solana:signTransaction` permissions only when a Solana payment requirement is selected. +- Balances are fetched directly from the relevant USDC mint (Token or Token-2022) via `@solana/kit`. diff --git a/typescript/packages/legacy/x402/src/paywall/baseTemplate.ts b/typescript/packages/legacy/x402/src/paywall/baseTemplate.ts new file mode 100644 index 000000000..09d9f77f2 --- /dev/null +++ b/typescript/packages/legacy/x402/src/paywall/baseTemplate.ts @@ -0,0 +1,22 @@ +// Empty paywall HTML template. Content here is static but can be changed at runtime. +/** + * Returns a base HTML template for the X402 paywall. + * This template contains the structure for payment prompts, wallet connection, + * and transaction details. + * + * @returns {string} HTML template string for the paywall + */ +export function getBaseTemplate(): string { + return ` + + + + + + + +
+ + + `; +} diff --git a/typescript/packages/legacy/x402/src/paywall/buffer-polyfill.ts b/typescript/packages/legacy/x402/src/paywall/buffer-polyfill.ts new file mode 100644 index 000000000..277f21650 --- /dev/null +++ b/typescript/packages/legacy/x402/src/paywall/buffer-polyfill.ts @@ -0,0 +1,6 @@ +// Inject Buffer polyfill +// Necessary for viem if it's not provided elsewhere, e.g. from a wallet extension + +import { Buffer } from "buffer"; + +globalThis.Buffer = Buffer; diff --git a/typescript/packages/x402/src/paywall/build.ts b/typescript/packages/legacy/x402/src/paywall/build.ts similarity index 100% rename from typescript/packages/x402/src/paywall/build.ts rename to typescript/packages/legacy/x402/src/paywall/build.ts diff --git a/typescript/packages/legacy/x402/src/paywall/gen/template.ts b/typescript/packages/legacy/x402/src/paywall/gen/template.ts new file mode 100644 index 000000000..399a6db1b --- /dev/null +++ b/typescript/packages/legacy/x402/src/paywall/gen/template.ts @@ -0,0 +1,6 @@ +// THIS FILE IS AUTO-GENERATED - DO NOT EDIT +/** + * The pre-built, self-contained paywall template with inlined CSS and JS + */ +export const PAYWALL_TEMPLATE = + '\n \n \n Payment Required\n \n
\n \n \n '; diff --git a/typescript/packages/x402/src/paywall/index.ts b/typescript/packages/legacy/x402/src/paywall/index.ts similarity index 100% rename from typescript/packages/x402/src/paywall/index.ts rename to typescript/packages/legacy/x402/src/paywall/index.ts diff --git a/typescript/packages/x402/src/paywall/index.tsx b/typescript/packages/legacy/x402/src/paywall/index.tsx similarity index 100% rename from typescript/packages/x402/src/paywall/index.tsx rename to typescript/packages/legacy/x402/src/paywall/index.tsx diff --git a/typescript/packages/x402/src/paywall/src/PaywallApp.tsx b/typescript/packages/legacy/x402/src/paywall/src/EvmPaywall.tsx similarity index 76% rename from typescript/packages/x402/src/paywall/src/PaywallApp.tsx rename to typescript/packages/legacy/x402/src/paywall/src/EvmPaywall.tsx index a1ca3212a..3988f54a9 100644 --- a/typescript/packages/x402/src/paywall/src/PaywallApp.tsx +++ b/typescript/packages/legacy/x402/src/paywall/src/EvmPaywall.tsx @@ -1,5 +1,3 @@ -"use client"; - import { FundButton, getOnrampBuyUrl } from "@coinbase/onchainkit/fund"; import { Avatar, Name } from "@coinbase/onchainkit/identity"; import { @@ -13,20 +11,30 @@ import { createPublicClient, formatUnits, http, publicActions } from "viem"; import { base, baseSepolia } from "viem/chains"; import { useAccount, useSwitchChain, useWalletClient } from "wagmi"; -import { selectPaymentRequirements } from "../../client"; +import type { PaymentRequirements } from "../../types/verify"; import { exact } from "../../schemes"; import { getUSDCBalance } from "../../shared/evm"; +import type { Network } from "../../types/shared"; import { Spinner } from "./Spinner"; import { useOnrampSessionToken } from "./useOnrampSessionToken"; import { ensureValidAmount } from "./utils"; +import { getNetworkDisplayName, isTestnetNetwork } from "./paywallUtils"; + +type EvmPaywallProps = { + paymentRequirement: PaymentRequirements; + onSuccessfulResponse: (response: Response) => Promise; +}; /** - * Main Paywall App Component + * Paywall experience for EVM networks. * - * @returns The PaywallApp component + * @param props - Component props. + * @param props.paymentRequirement - Payment requirement evaluated for the protected resource. + * @param props.onSuccessfulResponse - Callback fired once the 402 fetch succeeds. + * @returns JSX element. */ -export function PaywallApp() { +export function EvmPaywall({ paymentRequirement, onSuccessfulResponse }: EvmPaywallProps) { const { address, isConnected, chainId: connectedChainId } = useAccount(); const { switchChainAsync } = useSwitchChain(); const { data: wagmiWalletClient } = useWalletClient(); @@ -39,54 +47,75 @@ export function PaywallApp() { const [hideBalance, setHideBalance] = useState(true); const x402 = window.x402; - const amount = x402.amount || 0; - const testnet = x402.testnet ?? true; - const paymentChain = testnet ? baseSepolia : base; - const chainName = testnet ? "Base Sepolia" : "Base"; - const network = testnet ? "base-sepolia" : "base"; + const amount = + typeof x402.amount === "number" + ? x402.amount + : Number(paymentRequirement.maxAmountRequired ?? 0) / 1_000_000; + + const network = paymentRequirement.network as Network; + const paymentChain = network === "base-sepolia" ? baseSepolia : base; + const chainId = paymentChain.id; + const chainName = getNetworkDisplayName(network); + const testnet = isTestnetNetwork(network); const showOnramp = Boolean(!testnet && isConnected && x402.sessionTokenEndpoint); - useEffect(() => { - if (address) { - handleSwitchChain(); - checkUSDCBalance(); + const publicClient = useMemo( + () => + createPublicClient({ + chain: paymentChain, + transport: http(), + }).extend(publicActions), + [paymentChain], + ); + + const checkUSDCBalance = useCallback(async () => { + if (!address) { + return; } - }, [address]); + const balance = await getUSDCBalance(publicClient, address); + const formattedBalance = formatUnits(balance, 6); + setFormattedUsdcBalance(formattedBalance); + }, [address, publicClient]); - const publicClient = createPublicClient({ - chain: paymentChain, - transport: http(), - }).extend(publicActions); + const handleSwitchChain = useCallback(async () => { + if (isCorrectChain) { + return; + } - const paymentRequirements = x402 - ? selectPaymentRequirements([x402.paymentRequirements].flat(), network, "exact") - : null; + try { + setStatus(""); + await switchChainAsync({ chainId }); + await new Promise(resolve => setTimeout(resolve, 100)); + } catch (error) { + setStatus(error instanceof Error ? error.message : "Failed to switch network"); + } + }, [switchChainAsync, chainId, isCorrectChain]); useEffect(() => { - if (isConnected && paymentChain.id === connectedChainId) { + if (!address) { + return; + } + + void handleSwitchChain(); + void checkUSDCBalance(); + }, [address, handleSwitchChain, checkUSDCBalance]); + + useEffect(() => { + if (isConnected && chainId === connectedChainId) { setIsCorrectChain(true); setStatus(""); - } else if (isConnected && paymentChain.id !== connectedChainId) { + } else if (isConnected && chainId !== connectedChainId) { setIsCorrectChain(false); setStatus(`On the wrong network. Please switch to ${chainName}.`); } else { setIsCorrectChain(null); setStatus(""); } - }, [paymentChain.id, connectedChainId, isConnected]); - - const checkUSDCBalance = useCallback(async () => { - if (!address) { - return; - } - const balance = await getUSDCBalance(publicClient, address); - const formattedBalance = formatUnits(balance, 6); - setFormattedUsdcBalance(formattedBalance); - }, [address, publicClient]); + }, [chainId, connectedChainId, isConnected, chainName]); const onrampBuyUrl = useMemo(() => { if (!sessionToken) { - return; + return undefined; } return getOnrampBuyUrl({ presetFiatAmount: 2, @@ -95,41 +124,13 @@ export function PaywallApp() { }); }, [sessionToken]); - const handleSuccessfulResponse = useCallback(async (response: Response) => { - const contentType = response.headers.get("content-type"); - if (contentType && contentType.includes("text/html")) { - document.documentElement.innerHTML = await response.text(); - } else { - const blob = await response.blob(); - const url = window.URL.createObjectURL(blob); - window.location.href = url; - } - }, []); - - const handleSwitchChain = useCallback(async () => { - if (isCorrectChain) { - return; - } - - try { - setStatus(""); - await switchChainAsync({ chainId: paymentChain.id }); - // Small delay to let wallet settle - await new Promise(resolve => setTimeout(resolve, 100)); - } catch (error) { - setStatus(error instanceof Error ? error.message : "Failed to switch network"); - } - }, [switchChainAsync, paymentChain, isCorrectChain]); - const handlePayment = useCallback(async () => { - if (!address || !x402 || !paymentRequirements) { + if (!address || !x402) { return; } await handleSwitchChain(); - // Use wagmi's wallet client which has the correct provider for the connected wallet - // This avoids MetaMask conflicts when multiple wallets are installed if (!wagmiWalletClient) { setStatus("Wallet client not available. Please reconnect your wallet."); return; @@ -147,7 +148,7 @@ export function PaywallApp() { } setStatus("Creating payment signature..."); - const validPaymentRequirements = ensureValidAmount(paymentRequirements); + const validPaymentRequirements = ensureValidAmount(paymentRequirement); const initialPayment = await exact.evm.createPayment( walletClient, 1, @@ -165,12 +166,10 @@ export function PaywallApp() { }); if (response.ok) { - await handleSuccessfulResponse(response); + await onSuccessfulResponse(response); } else if (response.status === 402) { - // Try to parse error data, fallback to empty object if parsing fails const errorData = await response.json().catch(() => ({})); if (errorData && typeof errorData.x402Version === "number") { - // Retry with server's x402Version const retryPayment = await exact.evm.createPayment( walletClient, errorData.x402Version, @@ -186,7 +185,7 @@ export function PaywallApp() { }, }); if (retryResponse.ok) { - await handleSuccessfulResponse(retryResponse); + await onSuccessfulResponse(retryResponse); return; } else { throw new Error(`Payment retry failed: ${retryResponse.statusText}`); @@ -202,17 +201,19 @@ export function PaywallApp() { } finally { setIsPaying(false); } - }, [address, x402, paymentRequirements, publicClient, paymentChain, handleSwitchChain]); + }, [ + address, + x402, + paymentRequirement, + handleSwitchChain, + wagmiWalletClient, + publicClient, + chainName, + onSuccessfulResponse, + ]); - if (!x402 || !paymentRequirements) { - return ( -
-
-

Payment Required

-

Loading payment details...

-
-
- ); + if (!x402) { + return null; } return ( @@ -220,12 +221,12 @@ export function PaywallApp() {

Payment Required

- {paymentRequirements.description && `${paymentRequirements.description}.`} To access this + {paymentRequirement.description && `${paymentRequirement.description}.`} To access this content, please pay ${amount} {chainName} USDC.

{testnet && (

- Need Base Sepolia USDC?{" "} + Need {chainName} USDC?{" "} Get some here. diff --git a/typescript/packages/legacy/x402/src/paywall/src/PaywallApp.tsx b/typescript/packages/legacy/x402/src/paywall/src/PaywallApp.tsx new file mode 100644 index 000000000..21e56b81c --- /dev/null +++ b/typescript/packages/legacy/x402/src/paywall/src/PaywallApp.tsx @@ -0,0 +1,73 @@ +"use client"; + +import { useCallback, useMemo } from "react"; +import type { PaymentRequirements } from "../../types/verify"; +import { choosePaymentRequirement, isEvmNetwork, isSvmNetwork } from "./paywallUtils"; +import { EvmPaywall } from "./EvmPaywall"; +import { SolanaPaywall } from "./SolanaPaywall"; + +/** + * Main Paywall App Component + * + * @returns The PaywallApp component + */ +export function PaywallApp() { + const x402 = window.x402; + const testnet = x402.testnet ?? true; + + const paymentRequirement = useMemo(() => { + return choosePaymentRequirement(x402.paymentRequirements, testnet); + }, [testnet, x402.paymentRequirements]); + + const handleSuccessfulResponse = useCallback(async (response: Response) => { + const contentType = response.headers.get("content-type"); + if (contentType && contentType.includes("text/html")) { + document.documentElement.innerHTML = await response.text(); + } else { + const blob = await response.blob(); + const url = window.URL.createObjectURL(blob); + window.location.href = url; + } + }, []); + + if (!paymentRequirement) { + return ( +

+
+

Payment Required

+

Loading payment details...

+
+
+ ); + } + + if (isEvmNetwork(paymentRequirement.network)) { + return ( + + ); + } + + if (isSvmNetwork(paymentRequirement.network)) { + return ( + + ); + } + + return ( +
+
+

Payment Required

+

+ Unsupported network configuration for this paywall. Please contact the application + developer. +

+
+
+ ); +} diff --git a/typescript/packages/x402/src/paywall/src/Providers.tsx b/typescript/packages/legacy/x402/src/paywall/src/Providers.tsx similarity index 68% rename from typescript/packages/x402/src/paywall/src/Providers.tsx rename to typescript/packages/legacy/x402/src/paywall/src/Providers.tsx index 33718efed..4ae477154 100644 --- a/typescript/packages/x402/src/paywall/src/Providers.tsx +++ b/typescript/packages/legacy/x402/src/paywall/src/Providers.tsx @@ -1,6 +1,8 @@ import { OnchainKitProvider } from "@coinbase/onchainkit"; import type { ReactNode } from "react"; import { base, baseSepolia } from "viem/chains"; + +import { choosePaymentRequirement, isEvmNetwork } from "./paywallUtils"; import "./window.d.ts"; type ProvidersProps = { @@ -15,12 +17,19 @@ type ProvidersProps = { * @returns The Providers component */ export function Providers({ children }: ProvidersProps) { - const { testnet, cdpClientKey, appName, appLogo } = window.x402; + const { testnet = true, cdpClientKey, appName, appLogo, paymentRequirements } = window.x402; + const selectedRequirement = choosePaymentRequirement(paymentRequirements, testnet); + + if (!isEvmNetwork(selectedRequirement.network)) { + return <>{children}; + } + + const chain = selectedRequirement.network === "base-sepolia" ? baseSepolia : base; return ( Promise; +}; + +/** + * Paywall experience for Solana networks. + * + * @param props - Component props. + * @param props.paymentRequirement - Payment requirement enforced for Solana requests. + * @param props.onSuccessfulResponse - Callback invoked on successful 402 response. + * @returns JSX element. + */ +export function SolanaPaywall({ paymentRequirement, onSuccessfulResponse }: SolanaPaywallProps) { + const [status, setStatus] = useState(""); + const [isPaying, setIsPaying] = useState(false); + const walletOptions = useSolanaWalletOptions(); + const [selectedWalletValue, setSelectedWalletValue] = useState(""); + const [activeWallet, setActiveWallet] = useState(null); + const [activeAccount, setActiveAccount] = useState(null); + const [hideBalance, setHideBalance] = useState(true); + const attemptedSilentConnectWalletsRef = useRef>(new Set()); + + const { usdcBalance, formattedBalance, isFetchingBalance, refreshBalance, resetBalance } = + useSolanaBalance({ + activeAccount, + paymentRequirement, + onStatus: setStatus, + }); + + const x402 = window.x402; + const amount = + typeof x402.amount === "number" + ? x402.amount + : Number(paymentRequirement.maxAmountRequired ?? 0) / 1_000_000; + + const network = paymentRequirement.network; + const chainName = getNetworkDisplayName(network); + const targetChain = + network === "solana" ? ("solana:mainnet" as const) : ("solana:devnet" as const); + + const walletSigner = useSolanaSigner({ + activeWallet, + activeAccount, + targetChain, + }); + + useEffect(() => { + if (!selectedWalletValue && walletOptions.length === 1) { + setSelectedWalletValue(walletOptions[0].value); + } + }, [walletOptions, selectedWalletValue]); + + useEffect(() => { + if (!activeWallet) { + return; + } + + if (!walletOptions.some(option => option.wallet === activeWallet)) { + setActiveWallet(null); + setActiveAccount(null); + setSelectedWalletValue(""); + resetBalance(); + } + }, [walletOptions, activeWallet, resetBalance]); + + useSilentWalletConnection({ + walletOptions, + activeWallet, + targetChain, + attemptedSilentConnectWalletsRef, + setSelectedWalletValue, + setActiveWallet, + setActiveAccount, + refreshBalance, + setStatus, + }); + + useSolanaWalletEvents({ + activeWallet, + targetChain, + chainName, + setActiveWallet, + setActiveAccount, + setSelectedWalletValue, + setStatus, + resetBalance, + refreshBalance, + }); + + const handleConnect = useCallback(async () => { + const wallet = walletOptions.find( + (option: WalletOption) => option.value === selectedWalletValue, + )?.wallet; + if (!wallet) { + setStatus("Select a Solana wallet to continue."); + return; + } + + const connectFeature = getStandardConnectFeature(wallet); + if (!connectFeature) { + setStatus("Selected wallet does not support standard connect."); + return; + } + + try { + setStatus("Connecting to wallet..."); + const { accounts } = await connectFeature.connect(); + if (!accounts?.length) { + throw new Error("Wallet did not provide any accounts."); + } + + const matchingAccount = + accounts.find((account: WalletAccount) => account.chains?.includes(targetChain)) ?? + accounts[0]; + + setActiveWallet(wallet); + setActiveAccount(matchingAccount); + setStatus(""); + await refreshBalance(matchingAccount); + } catch (error) { + console.error("Failed to connect wallet", error); + setStatus(error instanceof Error ? error.message : "Failed to connect wallet."); + } + }, [walletOptions, selectedWalletValue, targetChain, refreshBalance]); + + const handleDisconnect = useCallback(async () => { + const disconnectFeature = activeWallet && getStandardDisconnectFeature(activeWallet); + if (disconnectFeature) { + await disconnectFeature.disconnect().catch(console.error); + } + + setActiveWallet(null); + setActiveAccount(null); + resetBalance(); + setStatus(""); + }, [activeWallet, resetBalance]); + + const handlePayment = useCallback(async () => { + if (!x402) { + return; + } + + if (!walletSigner || !activeAccount) { + setStatus("Connect a Solana wallet before paying."); + return; + } + + setIsPaying(true); + + try { + if (usdcBalance === null || usdcBalance === 0n) { + setStatus("Checking USDC balance..."); + const latestBalance = await refreshBalance(); + if (!latestBalance || latestBalance === 0n) { + throw new Error(`Insufficient balance. Make sure you have USDC on ${chainName}.`); + } + } + + setStatus("Creating payment transaction..."); + const validPaymentRequirements = ensureValidAmount(paymentRequirement); + + const createHeader = async (version: number) => + exact.svm.createPaymentHeader(walletSigner, version, validPaymentRequirements); + + const paymentHeader = await createHeader(1); + + setStatus("Requesting content with payment..."); + const response = await fetch(x402.currentUrl, { + headers: { + "X-PAYMENT": paymentHeader, + "Access-Control-Expose-Headers": "X-PAYMENT-RESPONSE", + }, + }); + + if (response.ok) { + await onSuccessfulResponse(response); + return; + } + + if (response.status === 402) { + const errorData = await response.json().catch(() => ({})); + if (errorData && typeof errorData.x402Version === "number") { + const retryPayment = await exact.svm.createPaymentHeader( + walletSigner, + errorData.x402Version, + validPaymentRequirements, + ); + + const retryResponse = await fetch(x402.currentUrl, { + headers: { + "X-PAYMENT": retryPayment, + "Access-Control-Expose-Headers": "X-PAYMENT-RESPONSE", + }, + }); + + if (retryResponse.ok) { + await onSuccessfulResponse(retryResponse); + return; + } + + throw new Error( + `Payment retry failed: ${retryResponse.status} ${retryResponse.statusText}`, + ); + } + + throw new Error(`Payment failed: ${response.statusText}`); + } + + throw new Error(`Payment failed: ${response.status} ${response.statusText}`); + } catch (error) { + setStatus(error instanceof Error ? error.message : "Payment failed."); + } finally { + setIsPaying(false); + } + }, [ + x402, + walletSigner, + activeAccount, + usdcBalance, + refreshBalance, + chainName, + paymentRequirement, + onSuccessfulResponse, + ]); + + return ( +
+
+

Payment Required

+

+ {paymentRequirement.description && `${paymentRequirement.description}.`} To access this + content, please pay ${amount} {chainName} USDC. +

+ {network === "solana-devnet" && ( +

+ Need Solana Devnet USDC?{" "} + + Request some here. + +

+ )} +
+ +
+
+
+ Wallet: + + {activeAccount + ? `${activeAccount.address.slice(0, 6)}...${activeAccount.address.slice(-4)}` + : "-"} + +
+
+ Available balance: + + {activeAccount ? ( + + ) : ( + "-" + )} + +
+
+ Amount: + ${amount} USDC +
+
+ Network: + {chainName} +
+
+ +
+ {activeAccount ? ( + + ) : ( + <> + + + + )} + {activeAccount && ( + + )} +
+ + {!walletOptions.length && ( +
+ Install a Solana wallet such as Phantom to continue, then refresh this page. +
+ )} + + {status &&
{status}
} +
+
+ ); +} diff --git a/typescript/packages/legacy/x402/src/paywall/src/Spinner.tsx b/typescript/packages/legacy/x402/src/paywall/src/Spinner.tsx new file mode 100644 index 000000000..905785c42 --- /dev/null +++ b/typescript/packages/legacy/x402/src/paywall/src/Spinner.tsx @@ -0,0 +1,20 @@ +/** + * Simple Spinner component for loading states + * + * @param props - The component props + * @param props.className - Optional CSS classes to apply to the spinner + * @returns The Spinner component + */ +export function Spinner({ className = "" }: { className?: string }) { + return ( +
+
+
+ ); +} diff --git a/typescript/packages/legacy/x402/src/paywall/src/paywallUtils.test.ts b/typescript/packages/legacy/x402/src/paywall/src/paywallUtils.test.ts new file mode 100644 index 000000000..4d65c90c4 --- /dev/null +++ b/typescript/packages/legacy/x402/src/paywall/src/paywallUtils.test.ts @@ -0,0 +1,82 @@ +import { describe, expect, it } from "vitest"; + +import type { PaymentRequirements } from "../../types/verify"; +import { + choosePaymentRequirement, + getNetworkDisplayName, + isEvmNetwork, + isSvmNetwork, + normalizePaymentRequirements, +} from "./paywallUtils"; + +const baseRequirement: PaymentRequirements = { + scheme: "exact", + network: "base", + maxAmountRequired: "1000", + resource: "https://example.com/protected", + description: "Base resource", + mimeType: "application/json", + payTo: "0x0000000000000000000000000000000000000001", + maxTimeoutSeconds: 60, + asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + extra: { + feePayer: "0x0000000000000000000000000000000000000003", + }, +}; + +const baseSepoliaRequirement: PaymentRequirements = { + ...baseRequirement, + network: "base-sepolia", + description: "Base Sepolia resource", + asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", +}; + +const solanaRequirement: PaymentRequirements = { + scheme: "exact", + network: "solana", + maxAmountRequired: "1000", + resource: "https://example.com/solana", + description: "Solana resource", + mimeType: "application/json", + payTo: "2Zt8RZ8kW1nWcJ6YyqHq9kTjY8QpM2R2t1xXUQ1e1VQa", + maxTimeoutSeconds: 60, + asset: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + extra: { + feePayer: "3d9yxXikBVYjgvPbJF4dPSt31Z87Nb5fV9jXYzQ3QAtc", + }, +}; + +describe("paywallUtils", () => { + it("normalizes single payment requirement into an array", () => { + const normalized = normalizePaymentRequirements(baseRequirement); + expect(normalized).toHaveLength(1); + expect(normalized[0]).toBe(baseRequirement); + }); + + it("selects base payment on mainnet preference", () => { + const selected = choosePaymentRequirement([solanaRequirement, baseRequirement], false); + expect(selected.network).toBe("base"); + }); + + it("selects base sepolia payment on testnet preference", () => { + const selected = choosePaymentRequirement([solanaRequirement, baseSepoliaRequirement], true); + expect(selected.network).toBe("base-sepolia"); + }); + + it("falls back to solana when no evm networks exist", () => { + const selected = choosePaymentRequirement([solanaRequirement], false); + expect(selected.network).toBe("solana"); + }); + + it("returns display names for known networks", () => { + expect(getNetworkDisplayName("base")).toBe("Base"); + expect(getNetworkDisplayName("solana-devnet")).toBe("Solana Devnet"); + }); + + it("identifies supported network families", () => { + expect(isEvmNetwork("base")).toBe(true); + expect(isEvmNetwork("solana")).toBe(false); + expect(isSvmNetwork("solana")).toBe(true); + expect(isSvmNetwork("base")).toBe(false); + }); +}); diff --git a/typescript/packages/legacy/x402/src/paywall/src/paywallUtils.ts b/typescript/packages/legacy/x402/src/paywall/src/paywallUtils.ts new file mode 100644 index 000000000..6f93c8fcd --- /dev/null +++ b/typescript/packages/legacy/x402/src/paywall/src/paywallUtils.ts @@ -0,0 +1,102 @@ +import { selectPaymentRequirements } from "../../client"; +import type { PaymentRequirements } from "../../types/verify"; +import { Network, SupportedEVMNetworks, SupportedSVMNetworks } from "../../types/shared"; + +const EVM_TESTNETS = new Set(["base-sepolia"]); +const SVM_TESTNETS = new Set(["solana-devnet"]); + +/** + * Normalizes the payment requirements into an array. + * + * @param paymentRequirements - A single requirement or a list of requirements. + * @returns An array of payment requirements. + */ +export function normalizePaymentRequirements( + paymentRequirements: PaymentRequirements | PaymentRequirements[], +): PaymentRequirements[] { + if (Array.isArray(paymentRequirements)) { + return paymentRequirements; + } + return [paymentRequirements]; +} + +/** + * Returns the preferred networks to attempt first when selecting a payment requirement. + * + * @param testnet - Whether the paywall is operating in testnet mode. + * @returns Ordered list of preferred networks. + */ +export function getPreferredNetworks(testnet: boolean): Network[] { + if (testnet) { + return ["base-sepolia", "solana-devnet"]; + } + return ["base", "solana"]; +} + +/** + * Selects the most appropriate payment requirement for the user. + * + * @param paymentRequirements - All available payment requirements. + * @param testnet - Whether the paywall is operating in testnet mode. + * @returns The selected payment requirement. + */ +export function choosePaymentRequirement( + paymentRequirements: PaymentRequirements | PaymentRequirements[], + testnet: boolean, +): PaymentRequirements { + const normalized = normalizePaymentRequirements(paymentRequirements); + const preferredNetworks = getPreferredNetworks(testnet); + + return selectPaymentRequirements([...normalized], preferredNetworks as Network[], "exact"); +} + +/** + * Determines if the provided network is an EVM network. + * + * @param network - The network to check. + * @returns True if the network is EVM based. + */ +export function isEvmNetwork(network: string): network is Network { + return SupportedEVMNetworks.includes(network as Network); +} + +/** + * Determines if the provided network is an SVM network. + * + * @param network - The network to check. + * @returns True if the network is SVM based. + */ +export function isSvmNetwork(network: string): network is Network { + return SupportedSVMNetworks.includes(network as Network); +} + +/** + * Provides a human-readable display name for a network. + * + * @param network - The network identifier. + * @returns A display name suitable for UI use. + */ +export function getNetworkDisplayName(network: Network): string { + switch (network) { + case "base": + return "Base"; + case "base-sepolia": + return "Base Sepolia"; + case "solana": + return "Solana"; + case "solana-devnet": + return "Solana Devnet"; + default: + return network; + } +} + +/** + * Indicates whether the provided network is a testnet. + * + * @param network - The network to evaluate. + * @returns True if the network is a recognized testnet. + */ +export function isTestnetNetwork(network: Network): boolean { + return EVM_TESTNETS.has(network) || SVM_TESTNETS.has(network); +} diff --git a/typescript/packages/legacy/x402/src/paywall/src/solana/features.ts b/typescript/packages/legacy/x402/src/paywall/src/solana/features.ts new file mode 100644 index 000000000..5c3574dc6 --- /dev/null +++ b/typescript/packages/legacy/x402/src/paywall/src/solana/features.ts @@ -0,0 +1,61 @@ +import { + StandardConnect, + StandardDisconnect, + StandardEvents, + type StandardConnectFeature, + type StandardDisconnectFeature, + type StandardEventsFeature, +} from "@wallet-standard/features"; +import { + SolanaSignTransaction, + type SolanaSignTransactionFeature, + type WalletWithSolanaFeatures, +} from "@solana/wallet-standard-features"; +import type { Wallet } from "@wallet-standard/base"; + +/** + * Type guard ensuring the wallet implements the Solana signing features. + * + * @param wallet - Wallet instance to inspect. + * @returns True when the wallet supports Solana signing. + */ +export const hasSolanaSigning = (wallet: Wallet): wallet is WalletWithSolanaFeatures => + SolanaSignTransaction in wallet.features; + +/** + * Extracts the Solana transaction signing feature when present. + * + * @param wallet - Wallet that may expose the signing capability. + * @returns The signing feature if available, otherwise undefined. + */ +export const getSolanaSignTransactionFeature = (wallet: WalletWithSolanaFeatures) => + (wallet.features as unknown as Partial)[SolanaSignTransaction]; + +/** + * Retrieves the standard connect feature from a wallet, if supported. + * + * @param wallet - Wallet under inspection. + * @returns The connect feature when present. + */ +export const getStandardConnectFeature = (wallet: WalletWithSolanaFeatures) => + (wallet.features as unknown as Partial)[StandardConnect]; + +/** + * Retrieves the standard events feature from a wallet, if supported. + * + * @param wallet - Wallet under inspection. + * @returns The events feature when present. + */ +export const getStandardEventsFeature = (wallet: WalletWithSolanaFeatures) => + (wallet.features as unknown as Partial)[StandardEvents]; + +/** + * Retrieves the standard disconnect feature from a wallet, if supported. + * + * @param wallet - Wallet under inspection. + * @returns The disconnect feature when present. + */ +export const getStandardDisconnectFeature = (wallet: WalletWithSolanaFeatures) => + (wallet.features as unknown as Partial)[StandardDisconnect]; + +export type { StandardEventsChangeProperties } from "@wallet-standard/features"; diff --git a/typescript/packages/legacy/x402/src/paywall/src/solana/types.ts b/typescript/packages/legacy/x402/src/paywall/src/solana/types.ts new file mode 100644 index 000000000..ee09f11da --- /dev/null +++ b/typescript/packages/legacy/x402/src/paywall/src/solana/types.ts @@ -0,0 +1,6 @@ +import type { WalletWithSolanaFeatures } from "@solana/wallet-standard-features"; + +export type WalletOption = { + value: string; + wallet: WalletWithSolanaFeatures; +}; diff --git a/typescript/packages/legacy/x402/src/paywall/src/solana/useSilentWalletConnection.ts b/typescript/packages/legacy/x402/src/paywall/src/solana/useSilentWalletConnection.ts new file mode 100644 index 000000000..65a340627 --- /dev/null +++ b/typescript/packages/legacy/x402/src/paywall/src/solana/useSilentWalletConnection.ts @@ -0,0 +1,97 @@ +import { useEffect } from "react"; +import type { MutableRefObject } from "react"; +import type { WalletAccount } from "@wallet-standard/base"; +import type { WalletWithSolanaFeatures } from "@solana/wallet-standard-features"; + +import { getStandardConnectFeature } from "./features"; +import type { WalletOption } from "./types"; + +type Params = { + walletOptions: WalletOption[]; + activeWallet: WalletWithSolanaFeatures | null; + targetChain: "solana:mainnet" | "solana:devnet"; + attemptedSilentConnectWalletsRef: MutableRefObject>; + setSelectedWalletValue: (value: string) => void; + setActiveWallet: (wallet: WalletWithSolanaFeatures | null) => void; + setActiveAccount: (account: WalletAccount | null) => void; + refreshBalance: (account?: WalletAccount | null) => Promise; + setStatus: (message: string) => void; +}; + +/** + * Attempts a silent connection with available wallets to restore prior authorization. + * + * @param params - Hook parameters controlling wallet state and callbacks. + * @param params.walletOptions - Wallets eligible for silent reconnection. + * @param params.activeWallet - Currently active wallet, if any. + * @param params.targetChain - Solana chain identifier targeted by the paywall. + * @param params.attemptedSilentConnectWalletsRef - Ref tracking wallets already attempted silently. + * @param params.setSelectedWalletValue - Setter for the currently selected wallet option. + * @param params.setActiveWallet - Setter storing the active wallet instance. + * @param params.setActiveAccount - Setter storing the active wallet account. + * @param params.refreshBalance - Callback used to refresh the USDC balance. + * @param params.setStatus - Setter used to surface user-visible status messages. + */ +export function useSilentWalletConnection({ + walletOptions, + activeWallet, + targetChain, + attemptedSilentConnectWalletsRef, + setSelectedWalletValue, + setActiveWallet, + setActiveAccount, + refreshBalance, + setStatus, +}: Params): void { + useEffect(() => { + if (activeWallet) { + return; + } + + for (const option of walletOptions) { + if (attemptedSilentConnectWalletsRef.current.has(option.value)) { + continue; + } + + attemptedSilentConnectWalletsRef.current.add(option.value); + const connectFeature = getStandardConnectFeature(option.wallet); + if (!connectFeature) { + continue; + } + + void (async () => { + try { + const { accounts } = await connectFeature.connect({ silent: true }); + if (!accounts?.length) { + return; + } + + const matchingAccount = + accounts.find((account: WalletAccount) => account.chains?.includes(targetChain)) ?? + accounts[0]; + if (!matchingAccount) { + return; + } + + setSelectedWalletValue(option.value); + setActiveWallet(option.wallet); + setActiveAccount(matchingAccount); + setStatus(""); + await refreshBalance(matchingAccount); + } catch { + // Wallet may throw if silent connect isn't supported or authorization is missing. Ignore. + } + })(); + } + }, [ + walletOptions, + activeWallet, + targetChain, + attemptedSilentConnectWalletsRef, + setSelectedWalletValue, + setActiveWallet, + setActiveAccount, + refreshBalance, + setStatus, + ]); +} diff --git a/typescript/packages/legacy/x402/src/paywall/src/solana/useSolanaBalance.ts b/typescript/packages/legacy/x402/src/paywall/src/solana/useSolanaBalance.ts new file mode 100644 index 000000000..412fb54aa --- /dev/null +++ b/typescript/packages/legacy/x402/src/paywall/src/solana/useSolanaBalance.ts @@ -0,0 +1,116 @@ +import { useCallback, useEffect, useState } from "react"; +import { formatUnits } from "viem"; +import type { WalletAccount } from "@wallet-standard/base"; +import type { PaymentRequirements } from "../../../types/verify"; +import { getRpcClient } from "../../../shared/svm/rpc"; +import type { Address } from "@solana/kit"; +import { + TOKEN_PROGRAM_ADDRESS, + fetchMaybeToken as fetchMaybeSplToken, +} from "@solana-program/token"; +import { + TOKEN_2022_PROGRAM_ADDRESS, + fetchMaybeToken as fetchMaybeToken2022, + fetchMint, + findAssociatedTokenPda, +} from "@solana-program/token-2022"; +import { address as toAddress } from "@solana/kit"; + +type Params = { + activeAccount: WalletAccount | null; + paymentRequirement: PaymentRequirements; + onStatus: (message: string) => void; +}; + +type BalanceState = { + usdcBalance: bigint | null; + formattedBalance: string; + isFetchingBalance: boolean; + refreshBalance: (account?: WalletAccount | null) => Promise; + resetBalance: () => void; +}; + +/** + * Tracks and refreshes the Solana USDC balance for the active account. + * + * @param params - Hook parameters containing account details and callbacks. + * @param params.activeAccount - Wallet account whose balance is being tracked. + * @param params.paymentRequirement - Payment requirement describing the asset to monitor. + * @param params.onStatus - Callback for reporting status messages to the UI. + * @returns Balance state and helper methods for refreshing/resetting data. + */ +export function useSolanaBalance({ + activeAccount, + paymentRequirement, + onStatus, +}: Params): BalanceState { + const [usdcBalance, setUsdcBalance] = useState(null); + const [formattedBalance, setFormattedBalance] = useState(""); + const [isFetchingBalance, setIsFetchingBalance] = useState(false); + + const resetBalance = useCallback(() => { + setUsdcBalance(null); + setFormattedBalance(""); + }, []); + + const refreshBalance = useCallback( + async (account: WalletAccount | null = activeAccount) => { + if (!account) { + resetBalance(); + return null; + } + + try { + setIsFetchingBalance(true); + + const rpc = getRpcClient(paymentRequirement.network); + const mint = await fetchMint(rpc, paymentRequirement.asset as Address); + const tokenProgramAddress = mint.programAddress; + const [ata] = await findAssociatedTokenPda({ + mint: paymentRequirement.asset as Address, + owner: toAddress(account.address), + tokenProgram: tokenProgramAddress, + }); + + let balance = 0n; + if (tokenProgramAddress.toString() === TOKEN_PROGRAM_ADDRESS.toString()) { + const tokenAccount = await fetchMaybeSplToken(rpc, ata); + if (tokenAccount.exists) { + balance = tokenAccount.data.amount; + } + } else if (tokenProgramAddress.toString() === TOKEN_2022_PROGRAM_ADDRESS.toString()) { + const tokenAccount = await fetchMaybeToken2022(rpc, ata); + if (tokenAccount.exists) { + balance = tokenAccount.data.amount; + } + } + + setUsdcBalance(balance); + setFormattedBalance(formatUnits(balance, mint.data.decimals)); + return balance; + } catch (error) { + console.error("Failed to fetch Solana USDC balance", error); + onStatus("Unable to read your USDC balance. Please retry."); + resetBalance(); + return null; + } finally { + setIsFetchingBalance(false); + } + }, + [activeAccount, paymentRequirement, onStatus, resetBalance], + ); + + useEffect(() => { + if (activeAccount) { + void refreshBalance(); + } + }, [activeAccount, refreshBalance]); + + return { + usdcBalance, + formattedBalance, + isFetchingBalance, + refreshBalance, + resetBalance, + }; +} diff --git a/typescript/packages/legacy/x402/src/paywall/src/solana/useSolanaSigner.ts b/typescript/packages/legacy/x402/src/paywall/src/solana/useSolanaSigner.ts new file mode 100644 index 000000000..8bc90c9eb --- /dev/null +++ b/typescript/packages/legacy/x402/src/paywall/src/solana/useSolanaSigner.ts @@ -0,0 +1,79 @@ +import { useMemo } from "react"; +import { + getTransactionDecoder, + getTransactionEncoder, + type SignatureDictionary, + type TransactionSigner, + address as toAddress, +} from "@solana/kit"; +import type { WalletAccount } from "@wallet-standard/base"; +import type { WalletWithSolanaFeatures } from "@solana/wallet-standard-features"; + +import { getSolanaSignTransactionFeature } from "./features"; + +type Params = { + activeWallet: WalletWithSolanaFeatures | null; + activeAccount: WalletAccount | null; + targetChain: "solana:mainnet" | "solana:devnet"; +}; + +/** + * Derives a transaction signer that proxies requests to the connected Solana wallet. + * + * @param params - Hook parameters defining the active wallet/account and chain target. + * @param params.activeWallet - Wallet currently selected by the user. + * @param params.activeAccount - Account inside the wallet authorised for signing. + * @param params.targetChain - Identifier of the Solana cluster to sign transactions for. + * @returns A transaction signer or null when the wallet cannot sign. + */ +export function useSolanaSigner({ + activeWallet, + activeAccount, + targetChain, +}: Params): TransactionSigner | null { + return useMemo(() => { + if (!activeWallet || !activeAccount) { + return null; + } + + const signFeature = getSolanaSignTransactionFeature(activeWallet); + if (!signFeature) { + return null; + } + + const signerAddress = toAddress(activeAccount.address); + const encoder = getTransactionEncoder(); + const decoder = getTransactionDecoder(); + + return { + address: signerAddress, + async signTransactions(transactions) { + const signatures: SignatureDictionary[] = []; + + for (const transaction of transactions) { + const serialized = new Uint8Array(encoder.encode(transaction)); + const [signed] = await signFeature.signTransaction({ + account: activeAccount, + transaction: serialized, + chain: targetChain, + }); + + const decodedTransaction = decoder.decode(new Uint8Array(signed.signedTransaction)); + const signature = decodedTransaction.signatures[signerAddress]; + + if (!signature) { + throw new Error("Wallet did not return a signature for the selected account."); + } + + signatures.push( + Object.freeze({ + [signerAddress]: signature, + }) as SignatureDictionary, + ); + } + + return signatures; + }, + }; + }, [activeWallet, activeAccount, targetChain]); +} diff --git a/typescript/packages/legacy/x402/src/paywall/src/solana/useSolanaWalletEvents.ts b/typescript/packages/legacy/x402/src/paywall/src/solana/useSolanaWalletEvents.ts new file mode 100644 index 000000000..f99d40a27 --- /dev/null +++ b/typescript/packages/legacy/x402/src/paywall/src/solana/useSolanaWalletEvents.ts @@ -0,0 +1,113 @@ +import { useEffect } from "react"; +import type { WalletAccount } from "@wallet-standard/base"; +import type { WalletWithSolanaFeatures } from "@solana/wallet-standard-features"; + +import { SolanaSignTransaction } from "@solana/wallet-standard-features"; + +import { getStandardEventsFeature, type StandardEventsChangeProperties } from "./features"; + +type Params = { + activeWallet: WalletWithSolanaFeatures | null; + targetChain: "solana:mainnet" | "solana:devnet"; + chainName: string; + setActiveWallet: (wallet: WalletWithSolanaFeatures | null) => void; + setActiveAccount: (account: WalletAccount | null) => void; + setSelectedWalletValue: (value: string) => void; + setStatus: (status: string) => void; + resetBalance: () => void; + refreshBalance: (account?: WalletAccount | null) => Promise; +}; + +/** + * Listens for wallet-standard change events and keeps local state in sync. + * + * @param params - Hook parameters describing wallet state handlers and dependencies. + * @param params.activeWallet - Wallet currently active in the UI. + * @param params.targetChain - Chain identifier expected for the session. + * @param params.chainName - Human-readable name of the active chain. + * @param params.setActiveWallet - Setter used to store the active wallet. + * @param params.setActiveAccount - Setter used to store the active account. + * @param params.setSelectedWalletValue - Setter for the selected wallet option value. + * @param params.setStatus - Setter for user-facing status messages. + * @param params.resetBalance - Helper to clear cached balance state. + * @param params.refreshBalance - Function that refreshes the cached balance. + */ +export function useSolanaWalletEvents({ + activeWallet, + targetChain, + chainName, + setActiveWallet, + setActiveAccount, + setSelectedWalletValue, + setStatus, + resetBalance, + refreshBalance, +}: Params): void { + useEffect(() => { + if (!activeWallet) { + return; + } + + const eventsFeature = getStandardEventsFeature(activeWallet); + if (!eventsFeature) { + return; + } + + const unsubscribe = eventsFeature.on("change", (properties: StandardEventsChangeProperties) => { + if (properties.features && !(SolanaSignTransaction in properties.features)) { + setActiveWallet(null); + setActiveAccount(null); + setSelectedWalletValue(""); + resetBalance(); + setStatus("Selected wallet no longer supports Solana signing. Please reconnect."); + return; + } + + if (properties.accounts) { + if (!properties.accounts.length) { + setActiveAccount(null); + resetBalance(); + setStatus("Wallet disconnected. Select a wallet to reconnect."); + return; + } + + const nextAccount = + properties.accounts.find((account: WalletAccount) => + account.chains?.includes(targetChain), + ) ?? + properties.accounts[0] ?? + null; + + setActiveAccount(nextAccount); + + if (!nextAccount) { + setStatus("No authorized Solana accounts available. Reconnect your wallet."); + resetBalance(); + return; + } + + if (nextAccount.chains?.includes(targetChain)) { + setStatus(""); + } else { + setStatus(`Switch your wallet to ${chainName} to continue.`); + } + + void refreshBalance(nextAccount); + } + }); + + return () => { + unsubscribe(); + }; + }, [ + activeWallet, + targetChain, + chainName, + setActiveWallet, + setActiveAccount, + setSelectedWalletValue, + setStatus, + resetBalance, + refreshBalance, + ]); +} diff --git a/typescript/packages/legacy/x402/src/paywall/src/solana/useSolanaWalletOptions.ts b/typescript/packages/legacy/x402/src/paywall/src/solana/useSolanaWalletOptions.ts new file mode 100644 index 000000000..13f04427b --- /dev/null +++ b/typescript/packages/legacy/x402/src/paywall/src/solana/useSolanaWalletOptions.ts @@ -0,0 +1,43 @@ +import { useEffect, useState } from "react"; +import { getWallets } from "@wallet-standard/app"; + +import { hasSolanaSigning } from "./features"; +import type { WalletOption } from "./types"; + +/** + * Subscribes to wallet-standard registrations and collects Solana-capable wallets. + * + * @returns Wallet options suitable for Solana interactions. + */ +export function useSolanaWalletOptions(): WalletOption[] { + const [walletOptions, setWalletOptions] = useState([]); + + useEffect(() => { + const walletsApi = getWallets(); + + const mapWallets = (): WalletOption[] => + walletsApi + .get() + .filter(hasSolanaSigning) + .map(wallet => ({ + value: wallet.name, + wallet, + })); + + setWalletOptions(mapWallets()); + + const offRegister = walletsApi.on("register", () => { + setWalletOptions(mapWallets()); + }); + const offUnregister = walletsApi.on("unregister", () => { + setWalletOptions(mapWallets()); + }); + + return () => { + offRegister(); + offUnregister(); + }; + }, []); + + return walletOptions; +} diff --git a/typescript/packages/x402/src/paywall/src/useOnrampSessionToken.ts b/typescript/packages/legacy/x402/src/paywall/src/useOnrampSessionToken.ts similarity index 100% rename from typescript/packages/x402/src/paywall/src/useOnrampSessionToken.ts rename to typescript/packages/legacy/x402/src/paywall/src/useOnrampSessionToken.ts diff --git a/typescript/packages/x402/src/paywall/src/utils.ts b/typescript/packages/legacy/x402/src/paywall/src/utils.ts similarity index 100% rename from typescript/packages/x402/src/paywall/src/utils.ts rename to typescript/packages/legacy/x402/src/paywall/src/utils.ts diff --git a/typescript/packages/x402/src/paywall/src/window.d.ts b/typescript/packages/legacy/x402/src/paywall/src/window.d.ts similarity index 100% rename from typescript/packages/x402/src/paywall/src/window.d.ts rename to typescript/packages/legacy/x402/src/paywall/src/window.d.ts diff --git a/typescript/packages/x402/src/paywall/styles.css b/typescript/packages/legacy/x402/src/paywall/styles.css similarity index 92% rename from typescript/packages/x402/src/paywall/styles.css rename to typescript/packages/legacy/x402/src/paywall/styles.css index 1b8fc417c..b60fd9d59 100644 --- a/typescript/packages/x402/src/paywall/styles.css +++ b/typescript/packages/legacy/x402/src/paywall/styles.css @@ -132,6 +132,21 @@ body { gap: 1rem; } +.input { + width: 100%; + padding: 0.75rem 1rem; + border-radius: 0.5rem; + border: 1px solid #d1d5db; + background-color: white; + transition: border-color 150ms, box-shadow 150ms; +} + +.input:focus { + outline: none; + border-color: var(--button-primary-color); + box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2); +} + .button { width: 100%; padding: 0.75rem 1rem; @@ -229,4 +244,4 @@ body { display: flex; justify-content: flex-end; align-items: center; -} \ No newline at end of file +} diff --git a/typescript/packages/x402/src/schemes/exact/evm/client.test.ts b/typescript/packages/legacy/x402/src/schemes/exact/evm/client.test.ts similarity index 100% rename from typescript/packages/x402/src/schemes/exact/evm/client.test.ts rename to typescript/packages/legacy/x402/src/schemes/exact/evm/client.test.ts diff --git a/typescript/packages/x402/src/schemes/exact/evm/client.ts b/typescript/packages/legacy/x402/src/schemes/exact/evm/client.ts similarity index 100% rename from typescript/packages/x402/src/schemes/exact/evm/client.ts rename to typescript/packages/legacy/x402/src/schemes/exact/evm/client.ts diff --git a/typescript/packages/x402/src/schemes/exact/evm/facilitator.ts b/typescript/packages/legacy/x402/src/schemes/exact/evm/facilitator.ts similarity index 100% rename from typescript/packages/x402/src/schemes/exact/evm/facilitator.ts rename to typescript/packages/legacy/x402/src/schemes/exact/evm/facilitator.ts diff --git a/typescript/packages/x402/src/schemes/exact/evm/index.ts b/typescript/packages/legacy/x402/src/schemes/exact/evm/index.ts similarity index 100% rename from typescript/packages/x402/src/schemes/exact/evm/index.ts rename to typescript/packages/legacy/x402/src/schemes/exact/evm/index.ts diff --git a/typescript/packages/x402/src/schemes/exact/evm/sign.ts b/typescript/packages/legacy/x402/src/schemes/exact/evm/sign.ts similarity index 100% rename from typescript/packages/x402/src/schemes/exact/evm/sign.ts rename to typescript/packages/legacy/x402/src/schemes/exact/evm/sign.ts diff --git a/typescript/packages/x402/src/schemes/exact/evm/utils/paymentUtils.test.ts b/typescript/packages/legacy/x402/src/schemes/exact/evm/utils/paymentUtils.test.ts similarity index 100% rename from typescript/packages/x402/src/schemes/exact/evm/utils/paymentUtils.test.ts rename to typescript/packages/legacy/x402/src/schemes/exact/evm/utils/paymentUtils.test.ts diff --git a/typescript/packages/x402/src/schemes/exact/evm/utils/paymentUtils.ts b/typescript/packages/legacy/x402/src/schemes/exact/evm/utils/paymentUtils.ts similarity index 100% rename from typescript/packages/x402/src/schemes/exact/evm/utils/paymentUtils.ts rename to typescript/packages/legacy/x402/src/schemes/exact/evm/utils/paymentUtils.ts diff --git a/typescript/packages/x402/src/schemes/exact/index.ts b/typescript/packages/legacy/x402/src/schemes/exact/index.ts similarity index 100% rename from typescript/packages/x402/src/schemes/exact/index.ts rename to typescript/packages/legacy/x402/src/schemes/exact/index.ts diff --git a/typescript/packages/x402/src/schemes/exact/svm/client.test.ts b/typescript/packages/legacy/x402/src/schemes/exact/svm/client.test.ts similarity index 100% rename from typescript/packages/x402/src/schemes/exact/svm/client.test.ts rename to typescript/packages/legacy/x402/src/schemes/exact/svm/client.test.ts diff --git a/typescript/packages/x402/src/schemes/exact/svm/client.ts b/typescript/packages/legacy/x402/src/schemes/exact/svm/client.ts similarity index 100% rename from typescript/packages/x402/src/schemes/exact/svm/client.ts rename to typescript/packages/legacy/x402/src/schemes/exact/svm/client.ts diff --git a/typescript/packages/x402/src/schemes/exact/svm/facilitator/index.ts b/typescript/packages/legacy/x402/src/schemes/exact/svm/facilitator/index.ts similarity index 100% rename from typescript/packages/x402/src/schemes/exact/svm/facilitator/index.ts rename to typescript/packages/legacy/x402/src/schemes/exact/svm/facilitator/index.ts diff --git a/typescript/packages/x402/src/schemes/exact/svm/facilitator/settle.test.ts b/typescript/packages/legacy/x402/src/schemes/exact/svm/facilitator/settle.test.ts similarity index 100% rename from typescript/packages/x402/src/schemes/exact/svm/facilitator/settle.test.ts rename to typescript/packages/legacy/x402/src/schemes/exact/svm/facilitator/settle.test.ts diff --git a/typescript/packages/x402/src/schemes/exact/svm/facilitator/settle.ts b/typescript/packages/legacy/x402/src/schemes/exact/svm/facilitator/settle.ts similarity index 100% rename from typescript/packages/x402/src/schemes/exact/svm/facilitator/settle.ts rename to typescript/packages/legacy/x402/src/schemes/exact/svm/facilitator/settle.ts diff --git a/typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.test.ts b/typescript/packages/legacy/x402/src/schemes/exact/svm/facilitator/verify.test.ts similarity index 83% rename from typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.test.ts rename to typescript/packages/legacy/x402/src/schemes/exact/svm/facilitator/verify.test.ts index 9f6d0c367..9547151ca 100644 --- a/typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.test.ts +++ b/typescript/packages/legacy/x402/src/schemes/exact/svm/facilitator/verify.test.ts @@ -269,15 +269,21 @@ describe("verify", () => { let mockTokenInstruction: any; let mockPaymentRequirements: PaymentRequirements; let mockRpc: any; + let mockSigner: TransactionSigner; beforeEach(() => { vi.clearAllMocks(); + mockSigner = { + address: "FeePayer111111111111111111111111111111111" as any, + signTransactions: vi.fn(), + } as TransactionSigner; mockTokenInstruction = { programAddress: { toString: () => TOKEN_2022_PROGRAM_ADDRESS.toString() }, accounts: { mint: { address: "mintAddress" }, destination: { address: "destinationAta" }, source: { address: "sourceAta" }, + authority: { address: "authorityAddress" }, }, data: { amount: 1000n, @@ -312,6 +318,7 @@ describe("verify", () => { { txHasCreateDestATAInstruction: false, }, + mockSigner, mockRpc, ), ).resolves.not.toThrow(); @@ -326,6 +333,7 @@ describe("verify", () => { { txHasCreateDestATAInstruction: false, }, + mockSigner, mockRpc, ), ).rejects.toThrow("invalid_exact_svm_payload_transaction_transfer_to_incorrect_ata"); @@ -343,6 +351,7 @@ describe("verify", () => { { txHasCreateDestATAInstruction: false, }, + mockSigner, mockRpc, ), ).rejects.toThrow("invalid_exact_svm_payload_transaction_receiver_ata_not_found"); @@ -360,6 +369,7 @@ describe("verify", () => { { txHasCreateDestATAInstruction: false, }, + mockSigner, mockRpc, ), ).rejects.toThrow("invalid_exact_svm_payload_transaction_sender_ata_not_found"); @@ -374,6 +384,7 @@ describe("verify", () => { { txHasCreateDestATAInstruction: false, }, + mockSigner, mockRpc, ), ).rejects.toThrow("invalid_exact_svm_payload_transaction_amount_mismatch"); @@ -391,6 +402,39 @@ describe("verify", () => { { txHasCreateDestATAInstruction: true, }, + mockSigner, + mockRpc, + ), + ).resolves.not.toThrow(); + }); + + it("should throw an error if the fee payer is the transfer authority", async () => { + mockTokenInstruction.accounts.authority.address = mockSigner.address; + + await expect( + verifyTransferCheckedInstruction( + mockTokenInstruction, + mockPaymentRequirements, + { + txHasCreateDestATAInstruction: false, + }, + mockSigner, + mockRpc, + ), + ).rejects.toThrow("invalid_exact_svm_payload_transaction_fee_payer_transferring_funds"); + }); + + it("should not throw if authority is different from fee payer", async () => { + mockTokenInstruction.accounts.authority.address = "DifferentAuthority111111111111111111111"; + + await expect( + verifyTransferCheckedInstruction( + mockTokenInstruction, + mockPaymentRequirements, + { + txHasCreateDestATAInstruction: false, + }, + mockSigner, mockRpc, ), ).resolves.not.toThrow(); @@ -435,11 +479,12 @@ describe("verify", () => { mockTransferInstruction = { programAddress: { toString: () => TOKEN_2022_PROGRAM_ADDRESS.toString() }, data: new Uint8Array([TokenInstruction.TransferChecked, 1, 2, 3, 4, 5, 6, 7, 8, 1, 1]), // needs to be valid transfer checked data - accounts: { - mint: { address: "mintAddress" }, - destination: { address: "destinationAta" }, - source: { address: "sourceAta" }, - }, + accounts: [ + { address: "sourceAta" }, + { address: "mintAddress" }, + { address: "destinationAta" }, + { address: "authorityAddress" }, + ], }; // mocks for happy path @@ -475,6 +520,7 @@ describe("verify", () => { mint: { address: "mintAddress" }, destination: { address: "destinationAta" }, source: { address: "sourceAta" }, + authority: { address: "authorityAddress" }, }, data: { amount: 1000n, @@ -545,6 +591,7 @@ describe("verify", () => { let mockTransferInstruction: any; let mockCreateATAInstruction: any; let mockRpc: any; + let mockSigner: TransactionSigner; beforeEach(() => { vi.clearAllMocks(); @@ -557,6 +604,10 @@ describe("verify", () => { asset: devnetUSDCAddress, } as any; mockRpc = {}; + mockSigner = { + address: "FeePayer111111111111111111111111111111111" as any, + signTransactions: vi.fn(), + } as TransactionSigner; mockComputeLimitInstruction = { programAddress: { toString: () => COMPUTE_BUDGET_PROGRAM_ADDRESS.toString() }, data: new Uint8Array([2, 100, 25, 0, 0]), @@ -568,18 +619,16 @@ describe("verify", () => { mockTransferInstruction = { programAddress: { toString: () => TOKEN_2022_PROGRAM_ADDRESS.toString() }, data: new Uint8Array([3, 1, 2, 3, 4, 5, 6, 7, 8, 1, 1]), // TransferChecked is 3 - accounts: { - mint: { address: devnetUSDCAddress }, - destination: { address: "destinationAta" }, - source: { address: "sourceAta" }, - }, + accounts: [ + { address: devnetUSDCAddress }, + { address: "destinationAta" }, + { address: "sourceAta" }, + { address: "authorityAddress" }, + ], }; mockCreateATAInstruction = { programAddress: { toString: () => "AssociatedTokenAccountProgram" }, - accounts: { - owner: { address: "payToAddress" }, - mint: { address: devnetUSDCAddress }, - }, + accounts: [{ address: "payToAddress" }, { address: devnetUSDCAddress }], data: new Uint8Array(), }; @@ -589,6 +638,7 @@ describe("verify", () => { mint: { address: devnetUSDCAddress }, destination: { address: "destinationAta" }, source: { address: "sourceAta" }, + authority: { address: "authorityAddress" }, }, data: { amount: 1000n }, } as any); @@ -613,7 +663,12 @@ describe("verify", () => { }; await expect( - verifyTransactionInstructions(mockTransactionMessage, mockPaymentRequirements, mockRpc), + verifyTransactionInstructions( + mockTransactionMessage, + mockPaymentRequirements, + mockSigner, + mockRpc, + ), ).rejects.toThrow("invalid_exact_svm_payload_transaction_instructions_length"); }); @@ -629,7 +684,12 @@ describe("verify", () => { }; await expect( - verifyTransactionInstructions(mockTransactionMessage, mockPaymentRequirements, mockRpc), + verifyTransactionInstructions( + mockTransactionMessage, + mockPaymentRequirements, + mockSigner, + mockRpc, + ), ).rejects.toThrow("invalid_exact_svm_payload_transaction_instructions_length"); }); @@ -648,7 +708,12 @@ describe("verify", () => { ] as any); await expect( - verifyTransactionInstructions(mockTransactionMessage, mockPaymentRequirements, mockRpc), + verifyTransactionInstructions( + mockTransactionMessage, + mockPaymentRequirements, + mockSigner, + mockRpc, + ), ).rejects.toThrow("invalid_exact_svm_payload_transaction_receiver_ata_not_found"); }); @@ -667,7 +732,12 @@ describe("verify", () => { }); await expect( - verifyTransactionInstructions(mockTransactionMessage, mockPaymentRequirements, mockRpc), + verifyTransactionInstructions( + mockTransactionMessage, + mockPaymentRequirements, + mockSigner, + mockRpc, + ), ).rejects.toThrow("invalid_exact_svm_payload_transaction_create_ata_instruction"); }); @@ -687,9 +757,155 @@ describe("verify", () => { }; await expect( - verifyTransactionInstructions(mockTransactionMessage, mockPaymentRequirements, mockRpc), + verifyTransactionInstructions( + mockTransactionMessage, + mockPaymentRequirements, + mockSigner, + mockRpc, + ), ).resolves.not.toThrow(); }); + + it("should throw an error if the fee payer address appears in any instruction's accounts", async () => { + const instructionWithFeePayer = { + programAddress: { toString: () => TOKEN_2022_PROGRAM_ADDRESS.toString() }, + data: new Uint8Array([3, 1, 2, 3, 4, 5, 6, 7, 8, 1, 1]), + accounts: [ + { address: "someOtherAddress" }, + { address: mockSigner.address }, + { address: "yetAnotherAddress" }, + ], + }; + + mockTransactionMessage = { + instructions: [ + mockComputeLimitInstruction, + mockComputePriceInstruction, + instructionWithFeePayer, + ], + }; + + await expect( + verifyTransactionInstructions( + mockTransactionMessage, + mockPaymentRequirements, + mockSigner, + mockRpc, + ), + ).rejects.toThrow( + "invalid_exact_svm_payload_transaction_fee_payer_included_in_instruction_accounts", + ); + }); + + it("should throw an error if the fee payer is in the compute limit instruction accounts", async () => { + const instructionWithFeePayer = { + ...mockComputeLimitInstruction, + accounts: [{ address: mockSigner.address }], + }; + + mockTransactionMessage = { + instructions: [ + instructionWithFeePayer, + mockComputePriceInstruction, + mockTransferInstruction, + ], + }; + + await expect( + verifyTransactionInstructions( + mockTransactionMessage, + mockPaymentRequirements, + mockSigner, + mockRpc, + ), + ).rejects.toThrow( + "invalid_exact_svm_payload_transaction_fee_payer_included_in_instruction_accounts", + ); + }); + + it("should throw an error if the fee payer is in the compute price instruction accounts", async () => { + const instructionWithFeePayer = { + ...mockComputePriceInstruction, + accounts: [{ address: mockSigner.address }], + }; + + mockTransactionMessage = { + instructions: [ + mockComputeLimitInstruction, + instructionWithFeePayer, + mockTransferInstruction, + ], + }; + + await expect( + verifyTransactionInstructions( + mockTransactionMessage, + mockPaymentRequirements, + mockSigner, + mockRpc, + ), + ).rejects.toThrow( + "invalid_exact_svm_payload_transaction_fee_payer_included_in_instruction_accounts", + ); + }); + + it("should throw an error if the fee payer is in the create ata instruction accounts", async () => { + const createAtaWithFeePayer = { + ...mockCreateATAInstruction, + accounts: [{ address: mockSigner.address }, { address: devnetUSDCAddress }], + }; + + mockTransactionMessage = { + instructions: [ + mockComputeLimitInstruction, + mockComputePriceInstruction, + createAtaWithFeePayer, + mockTransferInstruction, + ], + }; + + await expect( + verifyTransactionInstructions( + mockTransactionMessage, + mockPaymentRequirements, + mockSigner, + mockRpc, + ), + ).rejects.toThrow( + "invalid_exact_svm_payload_transaction_fee_payer_included_in_instruction_accounts", + ); + }); + + it("should throw an error if the fee payer is the transfer source", async () => { + const transferWithFeePayerSource = { + ...mockTransferInstruction, + accounts: [ + { address: mockSigner.address }, + { address: devnetUSDCAddress }, + { address: "destinationAta" }, + { address: "authorityAddress" }, + ], + }; + + mockTransactionMessage = { + instructions: [ + mockComputeLimitInstruction, + mockComputePriceInstruction, + transferWithFeePayerSource, + ], + }; + + await expect( + verifyTransactionInstructions( + mockTransactionMessage, + mockPaymentRequirements, + mockSigner, + mockRpc, + ), + ).rejects.toThrow( + "invalid_exact_svm_payload_transaction_fee_payer_included_in_instruction_accounts", + ); + }); }); describe("verifyComputeLimitInstruction", () => { diff --git a/typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.ts b/typescript/packages/legacy/x402/src/schemes/exact/svm/facilitator/verify.ts similarity index 94% rename from typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.ts rename to typescript/packages/legacy/x402/src/schemes/exact/svm/facilitator/verify.ts index 06bd985ca..e8d89e07d 100644 --- a/typescript/packages/x402/src/schemes/exact/svm/facilitator/verify.ts +++ b/typescript/packages/legacy/x402/src/schemes/exact/svm/facilitator/verify.ts @@ -77,7 +77,7 @@ export async function verify( const rpc = getRpcClient(paymentRequirements.network, config?.svmConfig?.rpcUrl); // perform transaction introspection to validate the transaction structure and details - await transactionIntrospection(svmPayload, paymentRequirements, config); + await transactionIntrospection(svmPayload, paymentRequirements, signer, config); // simulate the transaction to ensure it will execute successfully const simulateResult = await signAndSimulateTransaction(signer, decodedTransaction, rpc); @@ -155,11 +155,13 @@ export function verifySchemesAndNetworks( * * @param svmPayload - The SVM payload containing the transaction * @param paymentRequirements - The payment requirements to verify against + * @param signer - The signer that will sign the transaction * @param config - Optional configuration for X402 operations (e.g., custom RPC URLs) */ export async function transactionIntrospection( svmPayload: ExactSvmPayload, paymentRequirements: PaymentRequirements, + signer: TransactionSigner, config?: X402Config, ): Promise { const rpc = getRpcClient(paymentRequirements.network, config?.svmConfig?.rpcUrl); @@ -171,7 +173,7 @@ export async function transactionIntrospection( compiledTransactionMessage, ); - await verifyTransactionInstructions(transactionMessage, paymentRequirements, rpc); + await verifyTransactionInstructions(transactionMessage, paymentRequirements, signer, rpc); } /** @@ -179,12 +181,14 @@ export async function transactionIntrospection( * * @param transactionMessage - The transaction message to verify * @param paymentRequirements - The payment requirements to verify against + * @param signer - The signer that will sign the transaction * @param rpc - The RPC client to use for verifying account existence * @throws Error if the transaction does not contain the expected instructions */ export async function verifyTransactionInstructions( transactionMessage: CompilableTransactionMessage, paymentRequirements: PaymentRequirements, + signer: TransactionSigner, rpc: RpcDevnet | RpcMainnet, ) { // validate the number of expected instructions @@ -199,6 +203,15 @@ export async function verifyTransactionInstructions( verifyComputeLimitInstruction(transactionMessage.instructions[0]); verifyComputePriceInstruction(transactionMessage.instructions[1]); + // verify that the fee payer is not included in any instruction's accounts + transactionMessage.instructions.forEach(instruction => { + if (instruction.accounts?.some(account => account.address === signer.address)) { + throw new Error( + `invalid_exact_svm_payload_transaction_fee_payer_included_in_instruction_accounts`, + ); + } + }); + // verify that the transfer instruction is valid // this expects the destination ATA to already exist if (transactionMessage.instructions.length === 3) { @@ -208,6 +221,7 @@ export async function verifyTransactionInstructions( { txHasCreateDestATAInstruction: false, }, + signer, rpc, ); } @@ -222,6 +236,7 @@ export async function verifyTransactionInstructions( { txHasCreateDestATAInstruction: true, }, + signer, rpc, ); } @@ -338,6 +353,7 @@ export function verifyCreateATAInstruction( * @param paymentRequirements - The payment requirements to verify against * @param {object} options - The options for the verification of the transfer instruction * @param {boolean} options.txHasCreateDestATAInstruction - Whether the transaction has a create destination ATA instruction + * @param signer - The signer that will sign the transaction * @param rpc - The RPC client to use for verifying account existence * @throws Error if the transfer instruction is invalid */ @@ -348,6 +364,7 @@ export async function verifyTransferInstruction( >, paymentRequirements: PaymentRequirements, { txHasCreateDestATAInstruction }: { txHasCreateDestATAInstruction: boolean }, + signer: TransactionSigner, rpc: RpcDevnet | RpcMainnet, ) { // get a validated and parsed transferChecked instruction @@ -358,6 +375,7 @@ export async function verifyTransferInstruction( { txHasCreateDestATAInstruction, }, + signer, rpc, ); } @@ -369,6 +387,7 @@ export async function verifyTransferInstruction( * @param paymentRequirements - The payment requirements to verify against * @param {object} options - The options for the verification of the transfer checked instruction * @param {boolean} options.txHasCreateDestATAInstruction - Whether the transaction has a create destination ATA instruction + * @param signer - The signer that will sign the transaction * @param rpc - The RPC client to use for verifying account existence * @throws Error if the transfer checked instruction is invalid */ @@ -376,6 +395,7 @@ export async function verifyTransferCheckedInstruction( parsedInstruction: ReturnType, paymentRequirements: PaymentRequirements, { txHasCreateDestATAInstruction }: { txHasCreateDestATAInstruction: boolean }, + signer: TransactionSigner, rpc: RpcDevnet | RpcMainnet, ) { // get the token program address @@ -384,6 +404,11 @@ export async function verifyTransferCheckedInstruction( ? TOKEN_PROGRAM_ADDRESS : TOKEN_2022_PROGRAM_ADDRESS; + // verify that the fee payer is not transferring funds + if (parsedInstruction.accounts.authority.address === signer.address) { + throw new Error(`invalid_exact_svm_payload_transaction_fee_payer_transferring_funds`); + } + // get the expected receiver's ATA const payToATA = await findAssociatedTokenPda({ mint: paymentRequirements.asset as Address, diff --git a/typescript/packages/x402/src/schemes/exact/svm/index.ts b/typescript/packages/legacy/x402/src/schemes/exact/svm/index.ts similarity index 100% rename from typescript/packages/x402/src/schemes/exact/svm/index.ts rename to typescript/packages/legacy/x402/src/schemes/exact/svm/index.ts diff --git a/typescript/packages/x402/src/schemes/index.ts b/typescript/packages/legacy/x402/src/schemes/index.ts similarity index 100% rename from typescript/packages/x402/src/schemes/index.ts rename to typescript/packages/legacy/x402/src/schemes/index.ts diff --git a/typescript/packages/x402/src/schemes/utils/index.ts b/typescript/packages/legacy/x402/src/schemes/utils/index.ts similarity index 100% rename from typescript/packages/x402/src/schemes/utils/index.ts rename to typescript/packages/legacy/x402/src/schemes/utils/index.ts diff --git a/typescript/packages/x402/src/shared/base64.ts b/typescript/packages/legacy/x402/src/shared/base64.ts similarity index 100% rename from typescript/packages/x402/src/shared/base64.ts rename to typescript/packages/legacy/x402/src/shared/base64.ts diff --git a/typescript/packages/x402/src/shared/evm/erc20.ts b/typescript/packages/legacy/x402/src/shared/evm/erc20.ts similarity index 100% rename from typescript/packages/x402/src/shared/evm/erc20.ts rename to typescript/packages/legacy/x402/src/shared/evm/erc20.ts diff --git a/typescript/packages/x402/src/shared/evm/index.ts b/typescript/packages/legacy/x402/src/shared/evm/index.ts similarity index 100% rename from typescript/packages/x402/src/shared/evm/index.ts rename to typescript/packages/legacy/x402/src/shared/evm/index.ts diff --git a/typescript/packages/x402/src/shared/evm/usdc.ts b/typescript/packages/legacy/x402/src/shared/evm/usdc.ts similarity index 100% rename from typescript/packages/x402/src/shared/evm/usdc.ts rename to typescript/packages/legacy/x402/src/shared/evm/usdc.ts diff --git a/typescript/packages/x402/src/shared/index.ts b/typescript/packages/legacy/x402/src/shared/index.ts similarity index 100% rename from typescript/packages/x402/src/shared/index.ts rename to typescript/packages/legacy/x402/src/shared/index.ts diff --git a/typescript/packages/x402/src/shared/json.ts b/typescript/packages/legacy/x402/src/shared/json.ts similarity index 100% rename from typescript/packages/x402/src/shared/json.ts rename to typescript/packages/legacy/x402/src/shared/json.ts diff --git a/typescript/packages/x402/src/shared/middleware.test.ts b/typescript/packages/legacy/x402/src/shared/middleware.test.ts similarity index 100% rename from typescript/packages/x402/src/shared/middleware.test.ts rename to typescript/packages/legacy/x402/src/shared/middleware.test.ts diff --git a/typescript/packages/x402/src/shared/middleware.ts b/typescript/packages/legacy/x402/src/shared/middleware.ts similarity index 100% rename from typescript/packages/x402/src/shared/middleware.ts rename to typescript/packages/legacy/x402/src/shared/middleware.ts diff --git a/typescript/packages/x402/src/shared/network.ts b/typescript/packages/legacy/x402/src/shared/network.ts similarity index 100% rename from typescript/packages/x402/src/shared/network.ts rename to typescript/packages/legacy/x402/src/shared/network.ts diff --git a/typescript/packages/legacy/x402/src/shared/paywall.ts b/typescript/packages/legacy/x402/src/shared/paywall.ts new file mode 100644 index 000000000..83150ba0b --- /dev/null +++ b/typescript/packages/legacy/x402/src/shared/paywall.ts @@ -0,0 +1,81 @@ +import { PAYWALL_TEMPLATE } from "./gen/template"; +import { config } from "../types/shared/evm/config"; +import { PaymentRequirements } from "../types/verify"; + +interface PaywallOptions { + amount: number; + paymentRequirements: PaymentRequirements[]; + currentUrl: string; + testnet: boolean; + cdpClientKey?: string; + appName?: string; + appLogo?: string; + sessionTokenEndpoint?: string; +} + +/** + * Escapes a string for safe injection into JavaScript string literals + * + * @param str - The string to escape + * @returns The escaped string + */ +function escapeString(str: string): string { + return str + .replace(/\\/g, "\\\\") + .replace(/"/g, '\\"') + .replace(/'/g, "\\'") + .replace(/\n/g, "\\n") + .replace(/\r/g, "\\r") + .replace(/\t/g, "\\t"); +} + +/** + * Generates an HTML paywall page that allows users to pay for content access + * + * @param options - The options for generating the paywall + * @param options.amount - The amount to be paid in USD + * @param options.paymentRequirements - The payment requirements for the content + * @param options.currentUrl - The URL of the content being accessed + * @param options.testnet - Whether to use testnet or mainnet + * @param options.cdpClientKey - CDP client API key for OnchainKit + * @param options.appName - The name of the application to display in the wallet connection modal + * @param options.appLogo - The logo of the application to display in the wallet connection modal + * @param options.sessionTokenEndpoint - The API endpoint for generating session tokens for Onramp authentication + * @returns An HTML string containing the paywall page + */ +export function getPaywallHtml({ + amount, + testnet, + paymentRequirements, + currentUrl, + cdpClientKey, + appName, + appLogo, + sessionTokenEndpoint, +}: PaywallOptions): string { + const logOnTestnet = testnet + ? "console.log('Payment requirements initialized:', window.x402);" + : ""; + + // Create the configuration script to inject with proper escaping + const configScript = ` + `; + + // Inject the configuration script into the head + return PAYWALL_TEMPLATE.replace("", `${configScript}\n`); +} diff --git a/typescript/packages/x402/src/shared/svm/index.ts b/typescript/packages/legacy/x402/src/shared/svm/index.ts similarity index 100% rename from typescript/packages/x402/src/shared/svm/index.ts rename to typescript/packages/legacy/x402/src/shared/svm/index.ts diff --git a/typescript/packages/x402/src/shared/svm/rpc.test.ts b/typescript/packages/legacy/x402/src/shared/svm/rpc.test.ts similarity index 100% rename from typescript/packages/x402/src/shared/svm/rpc.test.ts rename to typescript/packages/legacy/x402/src/shared/svm/rpc.test.ts diff --git a/typescript/packages/x402/src/shared/svm/rpc.ts b/typescript/packages/legacy/x402/src/shared/svm/rpc.ts similarity index 100% rename from typescript/packages/x402/src/shared/svm/rpc.ts rename to typescript/packages/legacy/x402/src/shared/svm/rpc.ts diff --git a/typescript/packages/x402/src/shared/svm/transaction.test.ts b/typescript/packages/legacy/x402/src/shared/svm/transaction.test.ts similarity index 100% rename from typescript/packages/x402/src/shared/svm/transaction.test.ts rename to typescript/packages/legacy/x402/src/shared/svm/transaction.test.ts diff --git a/typescript/packages/x402/src/shared/svm/transaction.ts b/typescript/packages/legacy/x402/src/shared/svm/transaction.ts similarity index 100% rename from typescript/packages/x402/src/shared/svm/transaction.ts rename to typescript/packages/legacy/x402/src/shared/svm/transaction.ts diff --git a/typescript/packages/x402/src/shared/svm/wallet.ts b/typescript/packages/legacy/x402/src/shared/svm/wallet.ts similarity index 100% rename from typescript/packages/x402/src/shared/svm/wallet.ts rename to typescript/packages/legacy/x402/src/shared/svm/wallet.ts diff --git a/typescript/packages/x402/src/types/config.test.ts b/typescript/packages/legacy/x402/src/types/config.test.ts similarity index 100% rename from typescript/packages/x402/src/types/config.test.ts rename to typescript/packages/legacy/x402/src/types/config.test.ts diff --git a/typescript/packages/x402/src/types/config.ts b/typescript/packages/legacy/x402/src/types/config.ts similarity index 100% rename from typescript/packages/x402/src/types/config.ts rename to typescript/packages/legacy/x402/src/types/config.ts diff --git a/typescript/packages/x402/src/types/index.ts b/typescript/packages/legacy/x402/src/types/index.ts similarity index 100% rename from typescript/packages/x402/src/types/index.ts rename to typescript/packages/legacy/x402/src/types/index.ts diff --git a/typescript/packages/x402/src/types/shared/evm/config.ts b/typescript/packages/legacy/x402/src/types/shared/evm/config.ts similarity index 100% rename from typescript/packages/x402/src/types/shared/evm/config.ts rename to typescript/packages/legacy/x402/src/types/shared/evm/config.ts diff --git a/typescript/packages/x402/src/types/shared/evm/eip3009.ts b/typescript/packages/legacy/x402/src/types/shared/evm/eip3009.ts similarity index 100% rename from typescript/packages/x402/src/types/shared/evm/eip3009.ts rename to typescript/packages/legacy/x402/src/types/shared/evm/eip3009.ts diff --git a/typescript/packages/x402/src/types/shared/evm/erc20PermitABI.ts b/typescript/packages/legacy/x402/src/types/shared/evm/erc20PermitABI.ts similarity index 100% rename from typescript/packages/x402/src/types/shared/evm/erc20PermitABI.ts rename to typescript/packages/legacy/x402/src/types/shared/evm/erc20PermitABI.ts diff --git a/typescript/packages/x402/src/types/shared/evm/index.ts b/typescript/packages/legacy/x402/src/types/shared/evm/index.ts similarity index 100% rename from typescript/packages/x402/src/types/shared/evm/index.ts rename to typescript/packages/legacy/x402/src/types/shared/evm/index.ts diff --git a/typescript/packages/x402/src/types/shared/evm/wallet.test.ts b/typescript/packages/legacy/x402/src/types/shared/evm/wallet.test.ts similarity index 100% rename from typescript/packages/x402/src/types/shared/evm/wallet.test.ts rename to typescript/packages/legacy/x402/src/types/shared/evm/wallet.test.ts diff --git a/typescript/packages/x402/src/types/shared/evm/wallet.ts b/typescript/packages/legacy/x402/src/types/shared/evm/wallet.ts similarity index 100% rename from typescript/packages/x402/src/types/shared/evm/wallet.ts rename to typescript/packages/legacy/x402/src/types/shared/evm/wallet.ts diff --git a/typescript/packages/x402/src/types/shared/index.ts b/typescript/packages/legacy/x402/src/types/shared/index.ts similarity index 100% rename from typescript/packages/x402/src/types/shared/index.ts rename to typescript/packages/legacy/x402/src/types/shared/index.ts diff --git a/typescript/packages/x402/src/types/shared/middleware.ts b/typescript/packages/legacy/x402/src/types/shared/middleware.ts similarity index 100% rename from typescript/packages/x402/src/types/shared/middleware.ts rename to typescript/packages/legacy/x402/src/types/shared/middleware.ts diff --git a/typescript/packages/x402/src/types/shared/money.ts b/typescript/packages/legacy/x402/src/types/shared/money.ts similarity index 100% rename from typescript/packages/x402/src/types/shared/money.ts rename to typescript/packages/legacy/x402/src/types/shared/money.ts diff --git a/typescript/packages/x402/src/types/shared/network.ts b/typescript/packages/legacy/x402/src/types/shared/network.ts similarity index 100% rename from typescript/packages/x402/src/types/shared/network.ts rename to typescript/packages/legacy/x402/src/types/shared/network.ts diff --git a/typescript/packages/x402/src/types/shared/resource.ts b/typescript/packages/legacy/x402/src/types/shared/resource.ts similarity index 100% rename from typescript/packages/x402/src/types/shared/resource.ts rename to typescript/packages/legacy/x402/src/types/shared/resource.ts diff --git a/typescript/packages/x402/src/types/shared/svm/index.ts b/typescript/packages/legacy/x402/src/types/shared/svm/index.ts similarity index 100% rename from typescript/packages/x402/src/types/shared/svm/index.ts rename to typescript/packages/legacy/x402/src/types/shared/svm/index.ts diff --git a/typescript/packages/x402/src/types/shared/svm/regex.ts b/typescript/packages/legacy/x402/src/types/shared/svm/regex.ts similarity index 100% rename from typescript/packages/x402/src/types/shared/svm/regex.ts rename to typescript/packages/legacy/x402/src/types/shared/svm/regex.ts diff --git a/typescript/packages/x402/src/types/shared/wallet.ts b/typescript/packages/legacy/x402/src/types/shared/wallet.ts similarity index 100% rename from typescript/packages/x402/src/types/shared/wallet.ts rename to typescript/packages/legacy/x402/src/types/shared/wallet.ts diff --git a/typescript/packages/x402/src/types/verify/facilitator.ts b/typescript/packages/legacy/x402/src/types/verify/facilitator.ts similarity index 100% rename from typescript/packages/x402/src/types/verify/facilitator.ts rename to typescript/packages/legacy/x402/src/types/verify/facilitator.ts diff --git a/typescript/packages/x402/src/types/verify/index.ts b/typescript/packages/legacy/x402/src/types/verify/index.ts similarity index 100% rename from typescript/packages/x402/src/types/verify/index.ts rename to typescript/packages/legacy/x402/src/types/verify/index.ts diff --git a/typescript/packages/x402/src/types/verify/x402Specs.test.ts b/typescript/packages/legacy/x402/src/types/verify/x402Specs.test.ts similarity index 100% rename from typescript/packages/x402/src/types/verify/x402Specs.test.ts rename to typescript/packages/legacy/x402/src/types/verify/x402Specs.test.ts diff --git a/typescript/packages/x402/src/types/verify/x402Specs.ts b/typescript/packages/legacy/x402/src/types/verify/x402Specs.ts similarity index 98% rename from typescript/packages/x402/src/types/verify/x402Specs.ts rename to typescript/packages/legacy/x402/src/types/verify/x402Specs.ts index 0e666e95a..5f8670fc8 100644 --- a/typescript/packages/x402/src/types/verify/x402Specs.ts +++ b/typescript/packages/legacy/x402/src/types/verify/x402Specs.ts @@ -31,6 +31,8 @@ export const ErrorReasons = [ "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_fee_payer_included_in_instruction_accounts", + "invalid_exact_svm_payload_transaction_fee_payer_transferring_funds", "invalid_exact_svm_payload_transaction_not_a_transfer_instruction", "invalid_exact_svm_payload_transaction_receiver_ata_not_found", "invalid_exact_svm_payload_transaction_sender_ata_not_found", diff --git a/typescript/packages/x402/src/verify/index.ts b/typescript/packages/legacy/x402/src/verify/index.ts similarity index 100% rename from typescript/packages/x402/src/verify/index.ts rename to typescript/packages/legacy/x402/src/verify/index.ts diff --git a/typescript/packages/x402/src/verify/useFacilitator.test.ts b/typescript/packages/legacy/x402/src/verify/useFacilitator.test.ts similarity index 100% rename from typescript/packages/x402/src/verify/useFacilitator.test.ts rename to typescript/packages/legacy/x402/src/verify/useFacilitator.test.ts diff --git a/typescript/packages/x402/src/verify/useFacilitator.ts b/typescript/packages/legacy/x402/src/verify/useFacilitator.ts similarity index 100% rename from typescript/packages/x402/src/verify/useFacilitator.ts rename to typescript/packages/legacy/x402/src/verify/useFacilitator.ts diff --git a/typescript/packages/legacy/x402/tsconfig.json b/typescript/packages/legacy/x402/tsconfig.json new file mode 100644 index 000000000..31736873f --- /dev/null +++ b/typescript/packages/legacy/x402/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "lib": ["ES2020", "DOM", "dom.iterable", "esnext"], + "allowJs": false, + "checkJs": false, + "jsx": "react-jsx" + }, + "include": ["src"] +} diff --git a/typescript/packages/x402/tsup.config.ts b/typescript/packages/legacy/x402/tsup.config.ts similarity index 100% rename from typescript/packages/x402/tsup.config.ts rename to typescript/packages/legacy/x402/tsup.config.ts diff --git a/typescript/packages/legacy/x402/vitest.config.ts b/typescript/packages/legacy/x402/vitest.config.ts new file mode 100644 index 000000000..156f8c924 --- /dev/null +++ b/typescript/packages/legacy/x402/vitest.config.ts @@ -0,0 +1,10 @@ +import { loadEnv } from "vite"; +import { defineConfig } from "vitest/config"; +import tsconfigPaths from "vite-tsconfig-paths"; + +export default defineConfig(({ mode }) => ({ + test: { + env: loadEnv(mode, process.cwd(), ""), + }, + plugins: [tsconfigPaths({ projects: ["."] })], +})); diff --git a/typescript/packages/mcp/TODO.md b/typescript/packages/mcp/TODO.md new file mode 100644 index 000000000..7915fdd8d --- /dev/null +++ b/typescript/packages/mcp/TODO.md @@ -0,0 +1,10 @@ +# @x402/mcp + +## TODO + +The `@x402/mcp` package implements **x402 payment flows over the Model Context Protocol (MCP)** using JSON-RPC messaging. + +It wraps the `x402Client`, `x402Server`, and `x402Facilitator` classes to enable x402 payments within MCP request/response cycles — including tool calls, resource access, and initialization flows. + +Payment requirements are signaled using JSON-RPC `error` responses with `code: 402`, containing a `PaymentRequirementsResponse` in `error.data`. +Clients transmit payment payloads via the `_meta["x402/payment"]` field, and servers return settlement results in `_meta["x402/payment-response"]`. diff --git a/typescript/packages/mechanisms/evm/.prettierignore b/typescript/packages/mechanisms/evm/.prettierignore new file mode 100644 index 000000000..9fd1bade5 --- /dev/null +++ b/typescript/packages/mechanisms/evm/.prettierignore @@ -0,0 +1,7 @@ +docs/ +dist/ +node_modules/ +coverage/ +.github/ +**/**/*.json +*.md diff --git a/typescript/packages/mechanisms/evm/.prettierrc b/typescript/packages/mechanisms/evm/.prettierrc new file mode 100644 index 000000000..ffb416b74 --- /dev/null +++ b/typescript/packages/mechanisms/evm/.prettierrc @@ -0,0 +1,11 @@ +{ + "tabWidth": 2, + "useTabs": false, + "semi": true, + "singleQuote": false, + "trailingComma": "all", + "bracketSpacing": true, + "arrowParens": "avoid", + "printWidth": 100, + "proseWrap": "never" +} diff --git a/typescript/packages/mechanisms/evm/README.md b/typescript/packages/mechanisms/evm/README.md new file mode 100644 index 000000000..d07f9c8f6 --- /dev/null +++ b/typescript/packages/mechanisms/evm/README.md @@ -0,0 +1,45 @@ +# @x402/evm + +x402 Payment Protocol EVM Implementation + +## Installation + +```bash +npm install @x402/evm +``` + +## Usage + +```typescript +import { /* EVM implementation exports */ } from '@x402/evm'; +``` + +## Development + +### Build + +```bash +npm run build +``` + +### Test + +```bash +npm run test +``` + +### Lint + +```bash +npm run lint +``` + +### Format + +```bash +npm run format +``` + +## License + +Apache-2.0 diff --git a/typescript/packages/mechanisms/evm/TODO.md b/typescript/packages/mechanisms/evm/TODO.md new file mode 100644 index 000000000..74dfea291 --- /dev/null +++ b/typescript/packages/mechanisms/evm/TODO.md @@ -0,0 +1,74 @@ +# @x402/evm + +## Overview + +The `@x402/evm` package provides EVM blockchain implementations for x402 payment schemes. It serves as the **reference implementation** for how mechanism packages should be structured, providing scheme clients, facilitators, and resource services for EVM-compatible chains. + +## Current Implementation Status + +### Completed āœ… +- **EIP-3009 Support**: Full implementation for gasless token transfers + - Supports both v1 and v2 protocol versions +- **Exact Scheme**: Complete implementation for exact-value payments +- **Multi-chain Support**: Works with any EVM-compatible chain via network identifiers (e.g., `eip155:*`) + +### Architecture +The package exports three core classes following the x402 pattern: +- `ExactEvmClient`: Client-side payment creation and signing +- `ExactEvmFacilitator`: Facilitator for payment settlement +- `ExactEvmResourceService`: Server-side payment verification + +## Planned Expansions + +### 1. Permit2 Integration +**Goal**: Implement Uniswap's Permit2 for more efficient token approvals and transfers + +**Benefits**: +- Single approval for multiple transfers +- Improved gas efficiency +- Better security through expiring approvals +- Reduced transaction count for users + +**Implementation Notes**: +- Maintain backward compatibility with EIP-3009 +- Allow configuration to choose between EIP-3009 and Permit2 +- Consider auto-detection based on token contract capabilities + +### 2. Up-To Scheme Implementation +**Goal**: Support payments "up to" a maximum value, enabling flexible pricing models + +**Use Cases**: +- Metered API usage +- Variable-cost operations +- Pay-per-use services with caps + +**Requirements**: +- Define schema for up-to payment requirements +- Implement partial payment settlement +- Support refunds for unused amounts +- Handle edge cases around maximum values + +## Contributing Guidelines + +Before implementing these expansions: + +1. **Open a GitHub Issue** to discuss the approach + - Outline the implementation plan + - Consider backward compatibility + - Discuss any protocol changes needed + +2. **Follow the Reference Pattern** + - Review how the exact scheme is implemented + - Maintain consistency with the three-class export pattern + - Ensure compatibility with `@x402/core` abstractions + +3. **Testing Requirements** + - Unit tests for all new functionality + - Integration tests with `@x402/core` + - E2E test implementation in `/e2e` + +## Technical Notes + +- This package serves as the reference for other mechanism implementations (Solana, etc.) +- All exports should extend the base classes from `@x402/core/types` +- Maintain support for both x402 v1 and v2 protocols where applicable \ No newline at end of file diff --git a/typescript/packages/mechanisms/evm/eslint.config.js b/typescript/packages/mechanisms/evm/eslint.config.js new file mode 100644 index 000000000..a276444eb --- /dev/null +++ b/typescript/packages/mechanisms/evm/eslint.config.js @@ -0,0 +1,72 @@ +import js from "@eslint/js"; +import ts from "@typescript-eslint/eslint-plugin"; +import tsParser from "@typescript-eslint/parser"; +import prettier from "eslint-plugin-prettier"; +import jsdoc from "eslint-plugin-jsdoc"; +import importPlugin from "eslint-plugin-import"; + +export default [ + { + ignores: ["dist/**", "node_modules/**"], + }, + { + files: ["**/*.ts", "**/*.tsx"], + languageOptions: { + parser: tsParser, + sourceType: "module", + ecmaVersion: 2020, + globals: { + process: "readonly", + __dirname: "readonly", + module: "readonly", + require: "readonly", + Buffer: "readonly", + exports: "readonly", + setTimeout: "readonly", + clearTimeout: "readonly", + setInterval: "readonly", + clearInterval: "readonly", + }, + }, + plugins: { + "@typescript-eslint": ts, + prettier: prettier, + jsdoc: jsdoc, + import: importPlugin, + }, + rules: { + ...ts.configs.recommended.rules, + "import/first": "error", + "prettier/prettier": "error", + "@typescript-eslint/member-ordering": "error", + "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_$" }], + "jsdoc/tag-lines": ["error", "any", { startLines: 1 }], + "jsdoc/check-alignment": "error", + "jsdoc/no-undefined-types": "off", + "jsdoc/check-param-names": "error", + "jsdoc/check-tag-names": "error", + "jsdoc/check-types": "error", + "jsdoc/implements-on-classes": "error", + "jsdoc/require-description": "error", + "jsdoc/require-jsdoc": [ + "error", + { + require: { + FunctionDeclaration: true, + MethodDefinition: true, + ClassDeclaration: true, + ArrowFunctionExpression: false, + FunctionExpression: false, + }, + }, + ], + "jsdoc/require-param": "error", + "jsdoc/require-param-description": "error", + "jsdoc/require-param-type": "off", + "jsdoc/require-returns": "error", + "jsdoc/require-returns-description": "error", + "jsdoc/require-returns-type": "off", + "jsdoc/require-hyphen-before-param-description": ["error", "always"], + }, + }, +]; diff --git a/typescript/packages/mechanisms/evm/package.json b/typescript/packages/mechanisms/evm/package.json new file mode 100644 index 000000000..5cbb4b401 --- /dev/null +++ b/typescript/packages/mechanisms/evm/package.json @@ -0,0 +1,76 @@ +{ + "name": "@x402/evm", + "version": "0.1.0", + "main": "./dist/cjs/index.js", + "module": "./dist/esm/index.js", + "types": "./dist/cjs/index.d.ts", + "scripts": { + "start": "tsx --env-file=.env index.ts", + "build": "tsup", + "test": "vitest run", + "test:watch": "vitest", + "watch": "tsc --watch", + "format": "prettier -c .prettierrc --write \"**/*.{ts,js,cjs,json,md}\"", + "format:check": "prettier -c .prettierrc --check \"**/*.{ts,js,cjs,json,md}\"", + "lint": "eslint . --ext .ts --fix", + "lint:check": "eslint . --ext .ts" + }, + "keywords": [ + "x402", + "payment", + "protocol", + "evm", + "ethereum" + ], + "license": "Apache-2.0", + "author": "Coinbase Inc.", + "repository": "https://github.com/coinbase/x402", + "description": "x402 Payment Protocol EVM Implementation", + "devDependencies": { + "@eslint/js": "^9.24.0", + "@types/node": "^22.13.4", + "@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", + "tsup": "^8.4.0", + "tsx": "^4.19.2", + "typescript": "^5.7.3", + "vite": "^6.2.6", + "vite-tsconfig-paths": "^5.1.4", + "vitest": "^3.0.5" + }, + "dependencies": { + "@x402/core": "workspace:*", + "viem": "^2.21.26", + "zod": "^3.24.2" + }, + "exports": { + ".": { + "import": { + "types": "./dist/esm/index.d.mts", + "default": "./dist/esm/index.mjs" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + } + }, + "./v1": { + "import": { + "types": "./dist/esm/v1/index.d.mts", + "default": "./dist/esm/v1/index.mjs" + }, + "require": { + "types": "./dist/cjs/v1/index.d.ts", + "default": "./dist/cjs/v1/index.js" + } + } + }, + "files": [ + "dist" + ] +} diff --git a/typescript/packages/mechanisms/evm/src/constants.ts b/typescript/packages/mechanisms/evm/src/constants.ts new file mode 100644 index 000000000..abfb4c463 --- /dev/null +++ b/typescript/packages/mechanisms/evm/src/constants.ts @@ -0,0 +1,61 @@ +// EIP-3009 TransferWithAuthorization types for EIP-712 signing +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" }, + ], +} as const; + +// EIP3009 ABI for transferWithAuthorization function +export const eip3009ABI = [ + { + inputs: [ + { name: "from", type: "address" }, + { name: "to", type: "address" }, + { name: "value", type: "uint256" }, + { name: "validAfter", type: "uint256" }, + { name: "validBefore", type: "uint256" }, + { name: "nonce", type: "bytes32" }, + { name: "v", type: "uint8" }, + { name: "r", type: "bytes32" }, + { name: "s", type: "bytes32" }, + ], + name: "transferWithAuthorization", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { name: "from", type: "address" }, + { name: "to", type: "address" }, + { name: "value", type: "uint256" }, + { name: "validAfter", type: "uint256" }, + { name: "validBefore", type: "uint256" }, + { name: "nonce", type: "bytes32" }, + { name: "signature", type: "bytes" }, + ], + name: "transferWithAuthorization", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ name: "account", type: "address" }], + name: "balanceOf", + outputs: [{ name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "version", + outputs: [{ name: "", type: "string" }], + stateMutability: "view", + type: "function", + }, +] as const; diff --git a/typescript/packages/mechanisms/evm/src/exact/index.ts b/typescript/packages/mechanisms/evm/src/exact/index.ts new file mode 100644 index 000000000..42d2f9e1f --- /dev/null +++ b/typescript/packages/mechanisms/evm/src/exact/index.ts @@ -0,0 +1,553 @@ +import { getAddress, parseErc6492Signature } from "viem"; +import { + PaymentRequirements, + SchemeNetworkClient, + SchemeNetworkFacilitator, + SchemeNetworkService, +} from "@x402/core/types"; +import { ClientEvmSigner, FacilitatorEvmSigner } from "../signer"; +import { PaymentPayload, Price, AssetAmount, Network } from "@x402/core/types"; +import { ExactEvmPayloadV2 } from "../types"; +import { createNonce } from "../utils"; +import { authorizationTypes, eip3009ABI } from "../constants"; +import { SettleResponse, VerifyResponse } from "@x402/core/types"; + +/** + * EVM client implementation for the Exact payment scheme. + * + */ +export class ExactEvmClient implements SchemeNetworkClient { + readonly scheme = "exact"; + + /** + * Creates a new ExactEvmClient instance. + * + * @param signer - The EVM signer for client operations + */ + constructor(private readonly signer: ClientEvmSigner) {} + + /** + * Creates a payment payload for the Exact scheme. + * + * @param _ - The x402 version (unused) + * @param requirements - The payment requirements + * @returns Promise resolving to a payment payload + */ + async createPaymentPayload( + _: number, + requirements: PaymentRequirements, + ): Promise { + const nonce = createNonce(); + const now = Math.floor(Date.now() / 1000); + + const authorization: ExactEvmPayloadV2["authorization"] = { + from: this.signer.address, + to: getAddress(requirements.payTo), + value: requirements.amount, + validAfter: (now - 600).toString(), // 10 minutes before + validBefore: (now + requirements.maxTimeoutSeconds).toString(), + nonce, + }; + + // Sign the authorization + const signature = await this.signAuthorization(authorization, requirements); + + const payload: ExactEvmPayloadV2 = { + authorization, + signature, + }; + + return { + x402Version: 2, + scheme: requirements.scheme, + network: requirements.network, + payload, + accepted: requirements, + } as PaymentPayload; + } + + /** + * Sign the EIP-3009 authorization using EIP-712 + * + * @param authorization - The authorization to sign + * @param requirements - The payment requirements + * @returns Promise resolving to the signature + */ + private async signAuthorization( + authorization: ExactEvmPayloadV2["authorization"], + requirements: PaymentRequirements, + ): Promise<`0x${string}`> { + const chainId = parseInt(requirements.network.split(":")[1]); + + if (!requirements.extra?.name || !requirements.extra?.version) { + throw new Error( + `EIP-712 domain parameters (name, version) are required in payment requirements for asset ${requirements.asset}`, + ); + } + + const { name, version } = requirements.extra; + + const domain = { + name, + version, + chainId, + verifyingContract: getAddress(requirements.asset), + }; + + const message = { + from: getAddress(authorization.from), + to: getAddress(authorization.to), + value: BigInt(authorization.value), + validAfter: BigInt(authorization.validAfter), + validBefore: BigInt(authorization.validBefore), + nonce: authorization.nonce, + }; + + return await this.signer.signTypedData({ + domain, + types: authorizationTypes, + primaryType: "TransferWithAuthorization", + message, + }); + } +} + +/** + * EVM facilitator implementation for the Exact payment scheme. + */ +export class ExactEvmFacilitator implements SchemeNetworkFacilitator { + readonly scheme = "exact"; + + /** + * Creates a new ExactEvmFacilitator instance. + * + * @param signer - The EVM signer for facilitator operations + */ + constructor(private readonly signer: FacilitatorEvmSigner) {} + + /** + * Verifies a payment payload. + * + * @param payload - The payment payload to verify + * @param requirements - The payment requirements + * @returns Promise resolving to verification response + */ + async verify( + payload: PaymentPayload, + requirements: PaymentRequirements, + ): Promise { + const exactEvmPayload = payload.payload as ExactEvmPayloadV2; + + // Verify scheme matches + if (payload.scheme !== "exact" || requirements.scheme !== "exact") { + return { + isValid: false, + invalidReason: "unsupported_scheme", + payer: exactEvmPayload.authorization.from, + }; + } + + // Get chain configuration + if (!requirements.extra?.name || !requirements.extra?.version) { + return { + isValid: false, + invalidReason: "missing_eip712_domain", + payer: exactEvmPayload.authorization.from, + }; + } + + const { name, version } = requirements.extra; + const erc20Address = getAddress(requirements.asset); + + // Verify network matches + if (payload.network !== requirements.network) { + return { + isValid: false, + invalidReason: "network_mismatch", + payer: exactEvmPayload.authorization.from, + }; + } + + // Build typed data for signature verification + const permitTypedData = { + types: authorizationTypes, + primaryType: "TransferWithAuthorization" as const, + domain: { + name, + version, + chainId: parseInt(requirements.network.split(":")[1]), + verifyingContract: erc20Address, + }, + message: { + from: exactEvmPayload.authorization.from, + to: exactEvmPayload.authorization.to, + value: BigInt(exactEvmPayload.authorization.value), + validAfter: BigInt(exactEvmPayload.authorization.validAfter), + validBefore: BigInt(exactEvmPayload.authorization.validBefore), + nonce: exactEvmPayload.authorization.nonce, + }, + }; + + // Verify signature + try { + const recoveredAddress = await this.signer.verifyTypedData({ + address: exactEvmPayload.authorization.from, + ...permitTypedData, + signature: exactEvmPayload.signature!, + }); + + if (!recoveredAddress) { + return { + isValid: false, + invalidReason: "invalid_exact_evm_payload_signature", + payer: exactEvmPayload.authorization.from, + }; + } + } catch { + return { + isValid: false, + invalidReason: "invalid_exact_evm_payload_signature", + payer: exactEvmPayload.authorization.from, + }; + } + + // Verify payment recipient matches + if (getAddress(exactEvmPayload.authorization.to) !== getAddress(requirements.payTo)) { + return { + isValid: false, + invalidReason: "invalid_exact_evm_payload_recipient_mismatch", + payer: exactEvmPayload.authorization.from, + }; + } + + // Verify validBefore is in the future (with 6 second buffer for block time) + const now = Math.floor(Date.now() / 1000); + if (BigInt(exactEvmPayload.authorization.validBefore) < BigInt(now + 6)) { + return { + isValid: false, + invalidReason: "invalid_exact_evm_payload_authorization_valid_before", + payer: exactEvmPayload.authorization.from, + }; + } + + // Verify validAfter is not in the future + if (BigInt(exactEvmPayload.authorization.validAfter) > BigInt(now)) { + return { + isValid: false, + invalidReason: "invalid_exact_evm_payload_authorization_valid_after", + payer: exactEvmPayload.authorization.from, + }; + } + + // Check balance + try { + const balance = (await this.signer.readContract({ + address: erc20Address, + abi: eip3009ABI, + functionName: "balanceOf", + args: [exactEvmPayload.authorization.from], + })) as bigint; + + if (BigInt(balance) < BigInt(requirements.amount)) { + return { + isValid: false, + invalidReason: "insufficient_funds", + payer: exactEvmPayload.authorization.from, + }; + } + } catch { + // If we can't check balance, continue with other validations + } + + // Verify amount is sufficient + if (BigInt(exactEvmPayload.authorization.value) < BigInt(requirements.amount)) { + return { + isValid: false, + invalidReason: "invalid_exact_evm_payload_authorization_value", + payer: exactEvmPayload.authorization.from, + }; + } + + return { + isValid: true, + invalidReason: undefined, + payer: exactEvmPayload.authorization.from, + }; + } + + /** + * Settles a payment by executing the transfer. + * + * @param payload - The payment payload to settle + * @param requirements - The payment requirements + * @returns Promise resolving to settlement response + */ + async settle( + payload: PaymentPayload, + requirements: PaymentRequirements, + ): Promise { + const exactEvmPayload = payload.payload as ExactEvmPayloadV2; + + // Re-verify before settling + const valid = await this.verify(payload, requirements); + if (!valid.isValid) { + return { + success: false, + network: payload.network, + transaction: "", + errorReason: valid.invalidReason ?? "invalid_scheme", + payer: exactEvmPayload.authorization.from, + }; + } + + try { + // Parse ERC-6492 signature if applicable + const { signature } = parseErc6492Signature(exactEvmPayload.signature!); + + // Execute transferWithAuthorization + const tx = await this.signer.writeContract({ + address: getAddress(requirements.asset), + abi: eip3009ABI, + functionName: "transferWithAuthorization", + args: [ + getAddress(exactEvmPayload.authorization.from), + getAddress(exactEvmPayload.authorization.to), + BigInt(exactEvmPayload.authorization.value), + BigInt(exactEvmPayload.authorization.validAfter), + BigInt(exactEvmPayload.authorization.validBefore), + exactEvmPayload.authorization.nonce, + signature, + ], + }); + + // Wait for transaction confirmation + const receipt = await this.signer.waitForTransactionReceipt({ hash: tx }); + + if (receipt.status !== "success") { + return { + success: false, + errorReason: "invalid_transaction_state", + transaction: tx, + network: payload.network, + payer: exactEvmPayload.authorization.from, + }; + } + + return { + success: true, + transaction: tx, + network: payload.network, + payer: exactEvmPayload.authorization.from, + }; + } catch (error) { + console.error("Failed to settle transaction:", error); + return { + success: false, + errorReason: "transaction_failed", + transaction: "", + network: payload.network, + payer: exactEvmPayload.authorization.from, + }; + } + } +} + +/** + * EVM service implementation for the Exact payment scheme. + */ +export class ExactEvmService implements SchemeNetworkService { + readonly scheme = "exact"; + + /** + * Parses a price into an asset amount. + * + * @param price - The price to parse + * @param network - The network to use + * @returns The parsed asset amount + */ + parsePrice(price: Price, network: Network): AssetAmount { + // Handle pre-parsed price object + if (typeof price === "object" && price !== null && "amount" in price) { + if (!price.asset) { + throw new Error(`Asset address must be specified for price object on network ${network}`); + } + return { + amount: price.amount, + asset: price.asset, + extra: price.extra || {}, + }; + } + + // Parse string prices like "$0.10" or "0.10 USDC" + if (typeof price === "string") { + // Remove $ sign if present + const cleanPrice = price.replace(/^\$/, "").trim(); + + // Check if it contains a currency/asset identifier + const parts = cleanPrice.split(/\s+/); + if (parts.length === 2) { + // Format: "0.10 USDC" + const amount = this.convertToTokenAmount(parts[0], network); + const assetInfo = this.getAssetInfo(parts[1], network); + return { + amount, + asset: assetInfo.address, + extra: { + name: assetInfo.name, + version: assetInfo.version, + }, + }; + } else if (cleanPrice.match(/^\d+(\.\d+)?$/)) { + // Simple number format like "0.10" - assume USD/USDC + const amount = this.convertToTokenAmount(cleanPrice, network); + const assetInfo = this.getDefaultAsset(network); + return { + amount, + asset: assetInfo.address, + extra: { + name: assetInfo.name, + version: assetInfo.version, + }, + }; + } else { + throw new Error( + `Invalid price format: ${price}. Must specify currency (e.g., "0.10 USDC") or use simple number format.`, + ); + } + } + + // Handle number input - assume USD/USDC + if (typeof price === "number") { + const amount = this.convertToTokenAmount(price.toString(), network); + const assetInfo = this.getDefaultAsset(network); + return { + amount, + asset: assetInfo.address, + extra: { + name: assetInfo.name, + version: assetInfo.version, + }, + }; + } + + throw new Error(`Invalid price format: ${price}`); + } + + /** + * Build payment requirements for this scheme/network combination + * + * @param paymentRequirements - The base payment requirements + * @param supportedKind - The supported kind from facilitator (unused) + * @param supportedKind.x402Version - The x402 version + * @param supportedKind.scheme - The logical payment scheme + * @param supportedKind.network - The network identifier in CAIP-2 format + * @param supportedKind.extra - Optional extra metadata regarding scheme/network implementation details + * @param extensionKeys - Extension keys supported by the facilitator (unused) + * @returns Payment requirements ready to be sent to clients + */ + enhancePaymentRequirements( + paymentRequirements: PaymentRequirements, + supportedKind: { + x402Version: number; + scheme: string; + network: Network; + extra?: Record; + }, + extensionKeys: string[], + ): Promise { + // Mark unused parameters to satisfy linter + void supportedKind; + void extensionKeys; + return Promise.resolve(paymentRequirements); + } + + /** + * Convert decimal amount to token units (e.g., 0.10 -> 100000 for 6-decimal USDC) + * + * @param decimalAmount - The decimal amount to convert + * @param network - The network to use + * @returns The token amount as a string + */ + private convertToTokenAmount(decimalAmount: string, network: Network): string { + const decimals = this.getAssetDecimals(network); + const amount = parseFloat(decimalAmount); + if (isNaN(amount)) { + throw new Error(`Invalid amount: ${decimalAmount}`); + } + // Convert to smallest unit (e.g., for USDC with 6 decimals: 0.10 * 10^6 = 100000) + const tokenAmount = Math.floor(amount * Math.pow(10, decimals)); + return tokenAmount.toString(); + } + + /** + * Get the default asset info for a network (typically USDC) + * + * @param network - The network to get asset info for + * @returns The asset information including address, name, and version + */ + private getDefaultAsset(network: Network): { address: string; name: string; version: string } { + // Map of network to USDC info including EIP-712 domain parameters + const usdcInfo: Record = { + "eip155:8453": { + address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + name: "USD Coin", + version: "2", + }, // Base mainnet USDC + "eip155:84532": { + address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", + name: "USDC", + version: "2", + }, // Base Sepolia USDC + "eip155:1": { + address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + name: "USD Coin", + version: "2", + }, // Ethereum mainnet USDC + "eip155:11155111": { + address: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238", + name: "USDC", + version: "2", + }, // Sepolia USDC + }; + + const assetInfo = usdcInfo[network]; + if (!assetInfo) { + throw new Error(`No default asset configured for network ${network}`); + } + + return assetInfo; + } + + /** + * Get asset info for a given symbol on a network + * + * @param symbol - The asset symbol + * @param network - The network to use + * @returns The asset information including address, name, and version + */ + private getAssetInfo( + symbol: string, + network: Network, + ): { address: string; name: string; version: string } { + const upperSymbol = symbol.toUpperCase(); + + // For now, only support USDC + if (upperSymbol === "USDC" || upperSymbol === "USD") { + return this.getDefaultAsset(network); + } + + // Could extend to support other tokens + throw new Error(`Unsupported asset: ${symbol} on network ${network}`); + } + + /** + * Get the number of decimals for the asset + * + * @param _ - The network to use (unused) + * @returns The number of decimals for the asset + */ + private getAssetDecimals(_: Network): number { + // USDC has 6 decimals on all EVM chains + return 6; + } +} diff --git a/typescript/packages/mechanisms/evm/src/exact/v1/index.ts b/typescript/packages/mechanisms/evm/src/exact/v1/index.ts new file mode 100644 index 000000000..c8cf01479 --- /dev/null +++ b/typescript/packages/mechanisms/evm/src/exact/v1/index.ts @@ -0,0 +1,356 @@ +import { + PaymentPayload, + PaymentRequirements, + SchemeNetworkClient, + SchemeNetworkFacilitator, + SettleResponse, + VerifyResponse, +} from "@x402/core/types"; +import { PaymentRequirementsV1 } from "@x402/core/types/v1"; +import { getAddress, parseErc6492Signature } from "viem"; +import { authorizationTypes, eip3009ABI } from "../../constants"; +import { ClientEvmSigner, FacilitatorEvmSigner } from "../../signer"; +import { ExactEvmPayloadV1 } from "../../types"; +import { createNonce, getEvmChainId } from "../../utils"; + +/** + * EVM client implementation for the Exact payment scheme (V1). + */ +export class ExactEvmClientV1 implements SchemeNetworkClient { + readonly scheme = "exact"; + + /** + * Creates a new ExactEvmClientV1 instance. + * + * @param signer - The EVM signer for client operations + */ + constructor(private readonly signer: ClientEvmSigner) {} + + /** + * Creates a payment payload for the Exact scheme (V1). + * + * @param _ - The x402 version (unused) + * @param requirements - The payment requirements + * @returns Promise resolving to a payment payload + */ + async createPaymentPayload( + _: number, + requirements: PaymentRequirements, + ): Promise { + const requirementsV1 = requirements as unknown as PaymentRequirementsV1; + const nonce = createNonce(); + const now = Math.floor(Date.now() / 1000); + + const authorization: ExactEvmPayloadV1["authorization"] = { + from: this.signer.address, + to: getAddress(requirements.payTo), + value: requirementsV1.maxAmountRequired, + validAfter: (now - 600).toString(), // 10 minutes before + validBefore: (now + requirements.maxTimeoutSeconds).toString(), + nonce, + }; + + // Sign the authorization + const signature = await this.signAuthorization(authorization, requirementsV1); + + const payload: ExactEvmPayloadV1 = { + authorization, + signature, + }; + + return { + x402Version: 1, + scheme: requirements.scheme, + network: requirements.network, + payload, + } as unknown as PaymentPayload; + } + + /** + * Sign the EIP-3009 authorization using EIP-712 + * + * @param authorization - The authorization to sign + * @param requirements - The payment requirements + * @returns Promise resolving to the signature + */ + private async signAuthorization( + authorization: ExactEvmPayloadV1["authorization"], + requirements: PaymentRequirementsV1, + ): Promise<`0x${string}`> { + const chainId = getEvmChainId(requirements.network); + + if (!requirements.extra?.name || !requirements.extra?.version) { + throw new Error( + `EIP-712 domain parameters (name, version) are required in payment requirements for asset ${requirements.asset}`, + ); + } + + const { name, version } = requirements.extra; + + const domain = { + name, + version, + chainId, + verifyingContract: getAddress(requirements.asset), + }; + + const message = { + from: getAddress(authorization.from), + to: getAddress(authorization.to), + value: BigInt(authorization.value), + validAfter: BigInt(authorization.validAfter), + validBefore: BigInt(authorization.validBefore), + nonce: authorization.nonce, + }; + + return await this.signer.signTypedData({ + domain, + types: authorizationTypes, + primaryType: "TransferWithAuthorization", + message, + }); + } +} + +/** + * EVM facilitator implementation for the Exact payment scheme (V1). + */ +export class ExactEvmFacilitatorV1 implements SchemeNetworkFacilitator { + readonly scheme = "exact"; + + /** + * Creates a new ExactEvmFacilitatorV1 instance. + * + * @param signer - The EVM signer for facilitator operations + */ + constructor(private readonly signer: FacilitatorEvmSigner) {} + + /** + * Verifies a payment payload (V1). + * + * @param payload - The payment payload to verify + * @param requirements - The payment requirements + * @returns Promise resolving to verification response + */ + async verify( + payload: PaymentPayload, + requirements: PaymentRequirements, + ): Promise { + const requirementsV1 = requirements as unknown as PaymentRequirementsV1; + const exactEvmPayload = payload.payload as ExactEvmPayloadV1; + + // Verify scheme matches + if (payload.scheme !== "exact" || requirements.scheme !== "exact") { + return { + isValid: false, + invalidReason: "unsupported_scheme", + payer: exactEvmPayload.authorization.from, + }; + } + + // Get chain configuration + const chainId = getEvmChainId(payload.network); + + if (!requirements.extra?.name || !requirements.extra?.version) { + return { + isValid: false, + invalidReason: "missing_eip712_domain", + payer: exactEvmPayload.authorization.from, + }; + } + + const { name, version } = requirements.extra; + const erc20Address = getAddress(requirements.asset); + + // Verify network matches + if (payload.network !== requirements.network) { + return { + isValid: false, + invalidReason: "network_mismatch", + payer: exactEvmPayload.authorization.from, + }; + } + + // Build typed data for signature verification + const permitTypedData = { + types: authorizationTypes, + primaryType: "TransferWithAuthorization" as const, + domain: { + name, + version, + chainId, + verifyingContract: erc20Address, + }, + message: { + from: exactEvmPayload.authorization.from, + to: exactEvmPayload.authorization.to, + value: BigInt(exactEvmPayload.authorization.value), + validAfter: BigInt(exactEvmPayload.authorization.validAfter), + validBefore: BigInt(exactEvmPayload.authorization.validBefore), + nonce: exactEvmPayload.authorization.nonce, + }, + }; + + // Verify signature + try { + const recoveredAddress = await this.signer.verifyTypedData({ + address: exactEvmPayload.authorization.from, + ...permitTypedData, + signature: exactEvmPayload.signature!, + }); + + if (!recoveredAddress) { + return { + isValid: false, + invalidReason: "invalid_exact_evm_payload_signature", + payer: exactEvmPayload.authorization.from, + }; + } + } catch { + return { + isValid: false, + invalidReason: "invalid_exact_evm_payload_signature", + payer: exactEvmPayload.authorization.from, + }; + } + + // Verify payment recipient matches + if (getAddress(exactEvmPayload.authorization.to) !== getAddress(requirements.payTo)) { + return { + isValid: false, + invalidReason: "invalid_exact_evm_payload_recipient_mismatch", + payer: exactEvmPayload.authorization.from, + }; + } + + // Verify validBefore is in the future (with 6 second buffer for block time) + const now = Math.floor(Date.now() / 1000); + if (BigInt(exactEvmPayload.authorization.validBefore) < BigInt(now + 6)) { + return { + isValid: false, + invalidReason: "invalid_exact_evm_payload_authorization_valid_before", + payer: exactEvmPayload.authorization.from, + }; + } + + // Verify validAfter is not in the future + if (BigInt(exactEvmPayload.authorization.validAfter) > BigInt(now)) { + return { + isValid: false, + invalidReason: "invalid_exact_evm_payload_authorization_valid_after", + payer: exactEvmPayload.authorization.from, + }; + } + + // Check balance + try { + const balance = (await this.signer.readContract({ + address: erc20Address, + abi: eip3009ABI, + functionName: "balanceOf", + args: [exactEvmPayload.authorization.from], + })) as bigint; + + if (BigInt(balance) < BigInt(requirementsV1.maxAmountRequired)) { + return { + isValid: false, + invalidReason: "insufficient_funds", + payer: exactEvmPayload.authorization.from, + }; + } + } catch { + // If we can't check balance, continue with other validations + } + + // Verify amount is sufficient + if (BigInt(exactEvmPayload.authorization.value) < BigInt(requirementsV1.maxAmountRequired)) { + return { + isValid: false, + invalidReason: "invalid_exact_evm_payload_authorization_value", + payer: exactEvmPayload.authorization.from, + }; + } + + return { + isValid: true, + invalidReason: undefined, + payer: exactEvmPayload.authorization.from, + }; + } + + /** + * Settles a payment by executing the transfer (V1). + * + * @param payload - The payment payload to settle + * @param requirements - The payment requirements + * @returns Promise resolving to settlement response + */ + async settle( + payload: PaymentPayload, + requirements: PaymentRequirements, + ): Promise { + const exactEvmPayload = payload.payload as ExactEvmPayloadV1; + + // Re-verify before settling + const valid = await this.verify(payload, requirements); + if (!valid.isValid) { + return { + success: false, + network: payload.network, + transaction: "", + errorReason: valid.invalidReason ?? "invalid_scheme", + payer: exactEvmPayload.authorization.from, + }; + } + + try { + // Parse ERC-6492 signature if applicable + const { signature } = parseErc6492Signature(exactEvmPayload.signature!); + + // Execute transferWithAuthorization + const tx = await this.signer.writeContract({ + address: getAddress(requirements.asset), + abi: eip3009ABI, + functionName: "transferWithAuthorization", + args: [ + getAddress(exactEvmPayload.authorization.from), + getAddress(exactEvmPayload.authorization.to), + BigInt(exactEvmPayload.authorization.value), + BigInt(exactEvmPayload.authorization.validAfter), + BigInt(exactEvmPayload.authorization.validBefore), + exactEvmPayload.authorization.nonce, + signature, + ], + }); + + // Wait for transaction confirmation + const receipt = await this.signer.waitForTransactionReceipt({ hash: tx }); + + if (receipt.status !== "success") { + return { + success: false, + errorReason: "invalid_transaction_state", + transaction: tx, + network: payload.network, + payer: exactEvmPayload.authorization.from, + }; + } + + return { + success: true, + transaction: tx, + network: payload.network, + payer: exactEvmPayload.authorization.from, + }; + } catch (error) { + console.error("Failed to settle transaction:", error); + return { + success: false, + errorReason: "transaction_failed", + transaction: "", + network: payload.network, + payer: exactEvmPayload.authorization.from, + }; + } + } +} diff --git a/typescript/packages/mechanisms/evm/src/index.test.ts b/typescript/packages/mechanisms/evm/src/index.test.ts new file mode 100644 index 000000000..ad7656f88 --- /dev/null +++ b/typescript/packages/mechanisms/evm/src/index.test.ts @@ -0,0 +1,15 @@ +import { describe, it, expect } from "vitest"; + +describe("@x402/evm", () => { + it("should be defined", () => { + expect(true).toBe(true); + }); + + // TODO: Add actual tests for EVM mechanisms + it.todo("should create ExactEvmClient"); + it.todo("should create ExactEvmFacilitator"); + it.todo("should verify EVM payment signatures"); + it.todo("should settle EVM transactions"); + it.todo("should parse EVM prices"); + it.todo("should handle EIP-3009 authorizations"); +}); diff --git a/typescript/packages/mechanisms/evm/src/index.ts b/typescript/packages/mechanisms/evm/src/index.ts new file mode 100644 index 000000000..cf7f1d1e4 --- /dev/null +++ b/typescript/packages/mechanisms/evm/src/index.ts @@ -0,0 +1,12 @@ +/** + * @module @x402/evm - x402 Payment Protocol EVM Implementation + * + * This module provides the EVM-specific implementation of the x402 payment protocol. + */ + +// Export EVM implementation modules here +// The actual implementation logic will be added by copying from the core/src/schemes/evm folder + +export { ExactEvmClient, ExactEvmFacilitator, ExactEvmService } from "./exact"; +export { toClientEvmSigner, toFacilitatorEvmSigner } from "./signer"; +export type { ClientEvmSigner, FacilitatorEvmSigner } from "./signer"; diff --git a/typescript/packages/mechanisms/evm/src/signer.ts b/typescript/packages/mechanisms/evm/src/signer.ts new file mode 100644 index 000000000..5ea9db074 --- /dev/null +++ b/typescript/packages/mechanisms/evm/src/signer.ts @@ -0,0 +1,63 @@ +/** + * ClientEvmSigner - Used by x402 clients to sign payment authorizations + * This is typically a LocalAccount or wallet that holds private keys + * and can sign EIP-712 typed data for payment authorizations + */ +export type ClientEvmSigner = { + readonly address: `0x${string}`; + signTypedData(message: { + domain: Record; + types: Record; + primaryType: string; + message: Record; + }): Promise<`0x${string}`>; +}; + +/** + * FacilitatorEvmSigner - Used by x402 facilitators to verify and settle payments + * This is typically a viem PublicClient + WalletClient combination that can + * read contract state, verify signatures, write transactions, and wait for receipts + */ +export type FacilitatorEvmSigner = { + readContract(args: { + address: `0x${string}`; + abi: readonly unknown[]; + functionName: string; + args?: readonly unknown[]; + }): Promise; + verifyTypedData(args: { + address: `0x${string}`; + domain: Record; + types: Record; + primaryType: string; + message: Record; + signature: `0x${string}`; + }): Promise; + writeContract(args: { + address: `0x${string}`; + abi: readonly unknown[]; + functionName: string; + args: readonly unknown[]; + }): Promise<`0x${string}`>; + waitForTransactionReceipt(args: { hash: `0x${string}` }): Promise<{ status: string }>; +}; + +/** + * Converts a signer to a ClientEvmSigner + * + * @param signer - The signer to convert to a ClientEvmSigner + * @returns The converted signer + */ +export function toClientEvmSigner(signer: ClientEvmSigner): ClientEvmSigner { + return signer; +} + +/** + * Converts a client to a FacilitatorEvmSigner + * + * @param client - The client to convert to a FacilitatorEvmSigner + * @returns The converted client + */ +export function toFacilitatorEvmSigner(client: FacilitatorEvmSigner): FacilitatorEvmSigner { + return client; +} diff --git a/typescript/packages/mechanisms/evm/src/types.ts b/typescript/packages/mechanisms/evm/src/types.ts new file mode 100644 index 000000000..3bc53b501 --- /dev/null +++ b/typescript/packages/mechanisms/evm/src/types.ts @@ -0,0 +1,15 @@ +export type ExactEIP3009Payload = { + signature?: `0x${string}`; + authorization: { + from: `0x${string}`; + to: `0x${string}`; + value: string; + validAfter: string; + validBefore: string; + nonce: `0x${string}`; + }; +}; + +export type ExactEvmPayloadV1 = ExactEIP3009Payload; + +export type ExactEvmPayloadV2 = ExactEIP3009Payload; diff --git a/typescript/packages/mechanisms/evm/src/utils.ts b/typescript/packages/mechanisms/evm/src/utils.ts new file mode 100644 index 000000000..cb5908ceb --- /dev/null +++ b/typescript/packages/mechanisms/evm/src/utils.ts @@ -0,0 +1,40 @@ +import { toHex } from "viem"; +import { Network } from "@x402/core/types"; + +/** + * Extract chain ID from network string (e.g., "base-sepolia" -> 84532) + * Used by v1 implementations + * + * @param network - The network identifier + * @returns The numeric chain ID + */ +export function getEvmChainId(network: Network): number { + const networkMap: Record = { + base: 8453, + "base-sepolia": 84532, + ethereum: 1, + sepolia: 11155111, + polygon: 137, + "polygon-amoy": 80002, + }; + return networkMap[network] || 1; +} + +/** + * Create a random 32-byte nonce for authorization + * + * @returns A hex-encoded 32-byte nonce + */ +export function createNonce(): `0x${string}` { + // Use dynamic import to avoid require() in ESM context + const cryptoObj = + typeof globalThis.crypto !== "undefined" + ? globalThis.crypto + : (globalThis as { crypto?: Crypto }).crypto; + + if (!cryptoObj) { + throw new Error("Crypto API not available"); + } + + return toHex(cryptoObj.getRandomValues(new Uint8Array(32))); +} diff --git a/typescript/packages/mechanisms/evm/src/v1/index.ts b/typescript/packages/mechanisms/evm/src/v1/index.ts new file mode 100644 index 000000000..0771361d7 --- /dev/null +++ b/typescript/packages/mechanisms/evm/src/v1/index.ts @@ -0,0 +1 @@ +export { ExactEvmClientV1, ExactEvmFacilitatorV1 } from "../exact/v1"; diff --git a/typescript/packages/mechanisms/evm/tsconfig.json b/typescript/packages/mechanisms/evm/tsconfig.json new file mode 100644 index 000000000..ebd895041 --- /dev/null +++ b/typescript/packages/mechanisms/evm/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "lib": ["ES2020"], + "allowJs": false, + "checkJs": false + }, + "include": ["src"] +} diff --git a/typescript/packages/mechanisms/evm/tsup.config.ts b/typescript/packages/mechanisms/evm/tsup.config.ts new file mode 100644 index 000000000..65c111b9c --- /dev/null +++ b/typescript/packages/mechanisms/evm/tsup.config.ts @@ -0,0 +1,28 @@ +import { defineConfig } from "tsup"; + +const baseConfig = { + entry: { + index: "src/index.ts", + "v1/index": "src/v1/index.ts", + }, + dts: { + resolve: true, + }, + sourcemap: true, + target: "es2020", +}; + +export default defineConfig([ + { + ...baseConfig, + format: "esm", + outDir: "dist/esm", + clean: true, + }, + { + ...baseConfig, + format: "cjs", + outDir: "dist/cjs", + clean: false, + }, +]); diff --git a/typescript/packages/mechanisms/evm/vitest.config.ts b/typescript/packages/mechanisms/evm/vitest.config.ts new file mode 100644 index 000000000..156f8c924 --- /dev/null +++ b/typescript/packages/mechanisms/evm/vitest.config.ts @@ -0,0 +1,10 @@ +import { loadEnv } from "vite"; +import { defineConfig } from "vitest/config"; +import tsconfigPaths from "vite-tsconfig-paths"; + +export default defineConfig(({ mode }) => ({ + test: { + env: loadEnv(mode, process.cwd(), ""), + }, + plugins: [tsconfigPaths({ projects: ["."] })], +})); diff --git a/typescript/packages/mechanisms/svm/.prettierignore b/typescript/packages/mechanisms/svm/.prettierignore new file mode 100644 index 000000000..9fd1bade5 --- /dev/null +++ b/typescript/packages/mechanisms/svm/.prettierignore @@ -0,0 +1,7 @@ +docs/ +dist/ +node_modules/ +coverage/ +.github/ +**/**/*.json +*.md diff --git a/typescript/packages/mechanisms/svm/.prettierrc b/typescript/packages/mechanisms/svm/.prettierrc new file mode 100644 index 000000000..ffb416b74 --- /dev/null +++ b/typescript/packages/mechanisms/svm/.prettierrc @@ -0,0 +1,11 @@ +{ + "tabWidth": 2, + "useTabs": false, + "semi": true, + "singleQuote": false, + "trailingComma": "all", + "bracketSpacing": true, + "arrowParens": "avoid", + "printWidth": 100, + "proseWrap": "never" +} diff --git a/typescript/packages/mechanisms/svm/README.md b/typescript/packages/mechanisms/svm/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/typescript/packages/mechanisms/svm/TODO.md b/typescript/packages/mechanisms/svm/TODO.md new file mode 100644 index 000000000..705a83433 --- /dev/null +++ b/typescript/packages/mechanisms/svm/TODO.md @@ -0,0 +1,14 @@ +# @x402/solana + +## TODO + +The `@x402/solana` package defines the Solana implementations of various **x402 schemes**, starting with **exact**. + +It provides three core exports: +- A subclass of `SchemeNetworkClient` +- A subclass of `SchemeNetworkFacilitator` +- A subclass of `SchemeNetworkResourceService` + +As this package existed in v1, it also includes legacy exports under `/v1` for backward compatibility. + +**Tip** Follow `@x402/evm` as a reference. \ No newline at end of file diff --git a/typescript/packages/mechanisms/svm/eslint.config.js b/typescript/packages/mechanisms/svm/eslint.config.js new file mode 100644 index 000000000..a276444eb --- /dev/null +++ b/typescript/packages/mechanisms/svm/eslint.config.js @@ -0,0 +1,72 @@ +import js from "@eslint/js"; +import ts from "@typescript-eslint/eslint-plugin"; +import tsParser from "@typescript-eslint/parser"; +import prettier from "eslint-plugin-prettier"; +import jsdoc from "eslint-plugin-jsdoc"; +import importPlugin from "eslint-plugin-import"; + +export default [ + { + ignores: ["dist/**", "node_modules/**"], + }, + { + files: ["**/*.ts", "**/*.tsx"], + languageOptions: { + parser: tsParser, + sourceType: "module", + ecmaVersion: 2020, + globals: { + process: "readonly", + __dirname: "readonly", + module: "readonly", + require: "readonly", + Buffer: "readonly", + exports: "readonly", + setTimeout: "readonly", + clearTimeout: "readonly", + setInterval: "readonly", + clearInterval: "readonly", + }, + }, + plugins: { + "@typescript-eslint": ts, + prettier: prettier, + jsdoc: jsdoc, + import: importPlugin, + }, + rules: { + ...ts.configs.recommended.rules, + "import/first": "error", + "prettier/prettier": "error", + "@typescript-eslint/member-ordering": "error", + "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_$" }], + "jsdoc/tag-lines": ["error", "any", { startLines: 1 }], + "jsdoc/check-alignment": "error", + "jsdoc/no-undefined-types": "off", + "jsdoc/check-param-names": "error", + "jsdoc/check-tag-names": "error", + "jsdoc/check-types": "error", + "jsdoc/implements-on-classes": "error", + "jsdoc/require-description": "error", + "jsdoc/require-jsdoc": [ + "error", + { + require: { + FunctionDeclaration: true, + MethodDefinition: true, + ClassDeclaration: true, + ArrowFunctionExpression: false, + FunctionExpression: false, + }, + }, + ], + "jsdoc/require-param": "error", + "jsdoc/require-param-description": "error", + "jsdoc/require-param-type": "off", + "jsdoc/require-returns": "error", + "jsdoc/require-returns-description": "error", + "jsdoc/require-returns-type": "off", + "jsdoc/require-hyphen-before-param-description": ["error", "always"], + }, + }, +]; diff --git a/typescript/packages/mechanisms/svm/package.json b/typescript/packages/mechanisms/svm/package.json new file mode 100644 index 000000000..9e2773f6b --- /dev/null +++ b/typescript/packages/mechanisms/svm/package.json @@ -0,0 +1,75 @@ +{ + "name": "@x402/svm", + "version": "2.0.0", + "main": "./dist/cjs/index.js", + "module": "./dist/esm/index.js", + "types": "./dist/cjs/index.d.ts", + "scripts": { + "start": "tsx --env-file=.env index.ts", + "build": "tsup", + "test": "vitest run", + "test:watch": "vitest", + "watch": "tsc --watch", + "format": "prettier -c .prettierrc --write \"**/*.{ts,js,cjs,json,md}\"", + "format:check": "prettier -c .prettierrc --check \"**/*.{ts,js,cjs,json,md}\"", + "lint": "eslint . --ext .ts --fix", + "lint:check": "eslint . --ext .ts" + }, + "keywords": [ + "x402", + "payment", + "protocol", + "svm", + "solana" + ], + "license": "Apache-2.0", + "author": "Coinbase Inc.", + "repository": "https://github.com/coinbase/x402", + "description": "x402 Payment Protocol SVM Implementation", + "devDependencies": { + "@eslint/js": "^9.24.0", + "@types/node": "^22.13.4", + "@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", + "tsup": "^8.4.0", + "tsx": "^4.19.2", + "typescript": "^5.7.3", + "vite": "^6.2.6", + "vite-tsconfig-paths": "^5.1.4", + "vitest": "^3.0.5" + }, + "dependencies": { + "@x402/core": "workspace:*", + "zod": "^3.24.2" + }, + "exports": { + ".": { + "import": { + "types": "./dist/esm/index.d.mts", + "default": "./dist/esm/index.mjs" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + } + }, + "./v1": { + "import": { + "types": "./dist/esm/v1/index.d.mts", + "default": "./dist/esm/v1/index.mjs" + }, + "require": { + "types": "./dist/cjs/v1/index.d.ts", + "default": "./dist/cjs/v1/index.js" + } + } + }, + "files": [ + "dist" + ] +} diff --git a/typescript/packages/mechanisms/svm/src/exact/index.ts b/typescript/packages/mechanisms/svm/src/exact/index.ts new file mode 100644 index 000000000..cb0ff5c3b --- /dev/null +++ b/typescript/packages/mechanisms/svm/src/exact/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/typescript/packages/mechanisms/svm/src/exact/v1/index.ts b/typescript/packages/mechanisms/svm/src/exact/v1/index.ts new file mode 100644 index 000000000..cb0ff5c3b --- /dev/null +++ b/typescript/packages/mechanisms/svm/src/exact/v1/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/typescript/packages/mechanisms/svm/src/index.test.ts b/typescript/packages/mechanisms/svm/src/index.test.ts new file mode 100644 index 000000000..310fc467f --- /dev/null +++ b/typescript/packages/mechanisms/svm/src/index.test.ts @@ -0,0 +1,12 @@ +import { describe, it, expect } from "vitest"; + +describe("@x402/svm", () => { + it("should be defined", () => { + expect(true).toBe(true); + }); + + // TODO: Add actual tests for SVM mechanisms + it.todo("should handle Solana payments"); + it.todo("should verify SVM transactions"); + it.todo("should create payment payloads"); +}); diff --git a/typescript/packages/mechanisms/svm/src/index.ts b/typescript/packages/mechanisms/svm/src/index.ts new file mode 100644 index 000000000..ef3778046 --- /dev/null +++ b/typescript/packages/mechanisms/svm/src/index.ts @@ -0,0 +1,7 @@ +/** + * @module @x402/svm - x402 Payment Protocol SVM Implementation + * + * This module provides the SVM-specific implementation of the x402 payment protocol. + */ + +export {}; diff --git a/typescript/packages/mechanisms/svm/src/v1/index.ts b/typescript/packages/mechanisms/svm/src/v1/index.ts new file mode 100644 index 000000000..cb0ff5c3b --- /dev/null +++ b/typescript/packages/mechanisms/svm/src/v1/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/typescript/packages/mechanisms/svm/tsconfig.json b/typescript/packages/mechanisms/svm/tsconfig.json new file mode 100644 index 000000000..ebd895041 --- /dev/null +++ b/typescript/packages/mechanisms/svm/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "lib": ["ES2020"], + "allowJs": false, + "checkJs": false + }, + "include": ["src"] +} diff --git a/typescript/packages/mechanisms/svm/tsup.config.ts b/typescript/packages/mechanisms/svm/tsup.config.ts new file mode 100644 index 000000000..65c111b9c --- /dev/null +++ b/typescript/packages/mechanisms/svm/tsup.config.ts @@ -0,0 +1,28 @@ +import { defineConfig } from "tsup"; + +const baseConfig = { + entry: { + index: "src/index.ts", + "v1/index": "src/v1/index.ts", + }, + dts: { + resolve: true, + }, + sourcemap: true, + target: "es2020", +}; + +export default defineConfig([ + { + ...baseConfig, + format: "esm", + outDir: "dist/esm", + clean: true, + }, + { + ...baseConfig, + format: "cjs", + outDir: "dist/cjs", + clean: false, + }, +]); diff --git a/typescript/packages/mechanisms/svm/vitest.config.ts b/typescript/packages/mechanisms/svm/vitest.config.ts new file mode 100644 index 000000000..156f8c924 --- /dev/null +++ b/typescript/packages/mechanisms/svm/vitest.config.ts @@ -0,0 +1,10 @@ +import { loadEnv } from "vite"; +import { defineConfig } from "vitest/config"; +import tsconfigPaths from "vite-tsconfig-paths"; + +export default defineConfig(({ mode }) => ({ + test: { + env: loadEnv(mode, process.cwd(), ""), + }, + plugins: [tsconfigPaths({ projects: ["."] })], +})); diff --git a/typescript/packages/x402-next/tsconfig.json b/typescript/packages/x402-next/tsconfig.json deleted file mode 100644 index d14a78d24..000000000 --- a/typescript/packages/x402-next/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "allowJs": false, - "checkJs": false - }, - "include": ["src"] -} diff --git a/typescript/packages/x402/src/paywall/gen/template.ts b/typescript/packages/x402/src/paywall/gen/template.ts deleted file mode 100644 index af70413ea..000000000 --- a/typescript/packages/x402/src/paywall/gen/template.ts +++ /dev/null @@ -1,6 +0,0 @@ -// THIS FILE IS AUTO-GENERATED - DO NOT EDIT -/** - * The pre-built, self-contained paywall template with inlined CSS and JS - */ -export const PAYWALL_TEMPLATE = - '\n \n \n Payment Required\n \n
\n \n \n '; diff --git a/typescript/pnpm-lock.yaml b/typescript/pnpm-lock.yaml index 8cfeb3f98..f574a61ed 100644 --- a/typescript/pnpm-lock.yaml +++ b/typescript/pnpm-lock.yaml @@ -10,451 +10,503 @@ 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.6)(typescript@5.9.3) turbo: specifier: ^2.5.0 - version: 2.5.6 + version: 2.5.8 typescript: specifier: ^5.8.3 - version: 5.9.2 + version: 5.9.3 - packages/coinbase-x402: + packages/core: 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) - 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) - x402: - specifier: workspace:^ - version: link:../x402 zod: specifier: ^3.24.2 version: 3.25.76 devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.34.0 + version: 9.38.0 '@types/node': specifier: ^22.13.4 - version: 22.18.0 + version: 22.18.12 '@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.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) eslint: specifier: ^9.24.0 - version: 9.34.0(jiti@1.21.7) + version: 9.38.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.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.38.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.4(eslint@9.38.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.6)(typescript@5.9.3) tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.6 typescript: specifier: ^5.7.3 - version: 5.9.2 + version: 5.9.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.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6) 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.9.3)(vite@6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6)) 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.18.12)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.6) - packages/x402: + packages/http/axios: dependencies: - '@scure/base': - specifier: ^1.2.6 - 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))) - '@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))) - '@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)) + '@x402/core': + specifier: workspace:* + version: link:../../core + axios: + specifier: ^1.7.9 + version: 1.12.2 + zod: + specifier: ^3.24.2 + version: 3.25.76 + devDependencies: + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 + '@types/node': + specifier: ^22.13.4 + version: 22.18.12 + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.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.6)(typescript@5.9.3) + tsx: + specifier: ^4.19.2 + version: 4.20.6 + typescript: + specifier: ^5.7.3 + version: 5.9.3 + vite: + specifier: ^6.2.6 + version: 6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.9.3)(vite@6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6)) + vitest: + specifier: ^3.0.5 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.12)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.6) + + packages/http/express: + dependencies: + '@coinbase/cdp-sdk': + specifier: ^1.22.0 + version: 1.38.4(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(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.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.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@x402/core': + specifier: workspace:^ + version: link:../../core + '@x402/paywall': + specifier: workspace:* + version: link:../paywall + 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) - 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.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(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)(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) - '@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) '@eslint/js': specifier: ^9.24.0 - version: 9.34.0 + version: 9.38.0 + '@types/express': + specifier: ^5.0.1 + version: 5.0.3 '@types/node': specifier: ^22.13.4 - version: 22.18.0 - '@types/react': - specifier: ^19 - version: 19.1.12 - '@types/react-dom': - specifier: ^19 - version: 19.1.9(@types/react@19.1.12) + version: 22.18.12 '@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.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) '@typescript-eslint/parser': specifier: ^8.29.1 - version: 8.42.0(eslint@9.34.0(jiti@1.21.7))(typescript@5.9.2) - '@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) - '@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)) - buffer: - specifier: ^6.0.3 - version: 6.0.3 - esbuild: - specifier: ^0.25.4 - version: 0.25.9 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) eslint: specifier: ^9.24.0 - version: 9.34.0(jiti@1.21.7) + version: 9.38.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.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.38.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.4(eslint@9.38.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 - react-dom: - specifier: ^19.0.0 - 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.6)(typescript@5.9.3) tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.6 typescript: specifier: ^5.7.3 - version: 5.9.2 + version: 5.9.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.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6) 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.9.3)(vite@6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6)) 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.18.12)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.6) - packages/x402-axios: + packages/http/fetch: dependencies: - axios: - specifier: ^1.7.9 - version: 1.11.0 + '@x402/core': + specifier: workspace:^ + version: link:../../core 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) - x402: - specifier: workspace:^ - version: link:../x402 + version: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) zod: specifier: ^3.24.2 version: 3.25.76 devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.34.0 + version: 9.38.0 '@types/node': specifier: ^22.13.4 - version: 22.18.0 + version: 22.18.12 '@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.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) eslint: specifier: ^9.24.0 - version: 9.34.0(jiti@1.21.7) + version: 9.38.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.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.38.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.4(eslint@9.38.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.6)(typescript@5.9.3) tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.6 typescript: specifier: ^5.7.3 - version: 5.9.2 + version: 5.9.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.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6) 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.9.3)(vite@6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6)) 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.18.12)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.6) - packages/x402-express: + packages/http/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) - '@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)) - 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) - x402: - specifier: workspace:^ - version: link:../x402 + '@x402/core': + specifier: workspace:* + version: link:../../core + hono: + specifier: ^4.7.1 + version: 4.10.2 zod: specifier: ^3.24.2 version: 3.25.76 devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.34.0 - '@types/express': - specifier: ^5.0.1 - version: 5.0.3 + version: 9.38.0 '@types/node': specifier: ^22.13.4 - version: 22.18.0 + version: 22.18.12 '@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.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) eslint: specifier: ^9.24.0 - version: 9.34.0(jiti@1.21.7) + version: 9.38.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.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.38.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.4(eslint@9.38.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.6)(typescript@5.9.3) tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.6 typescript: specifier: ^5.7.3 - version: 5.9.2 + version: 5.9.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.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6) 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.9.3)(vite@6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6)) 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.18.12)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.6) - packages/x402-fetch: + packages/http/next: 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) - x402: - specifier: workspace:^ - version: link:../x402 + '@x402/core': + specifier: workspace:* + version: link:../../core + next: + specifier: ^15.0.0 + version: 15.5.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) zod: specifier: ^3.24.2 version: 3.25.76 devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.34.0 + version: 9.38.0 '@types/node': specifier: ^22.13.4 - version: 22.18.0 + version: 22.18.12 '@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.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) eslint: specifier: ^9.24.0 - version: 9.34.0(jiti@1.21.7) + version: 9.38.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.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.38.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.4(eslint@9.38.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.6)(typescript@5.9.3) tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.6 typescript: specifier: ^5.7.3 - version: 5.9.2 + version: 5.9.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.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6) 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.9.3)(vite@6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6)) 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.18.12)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.6) - packages/x402-hono: + packages/http/paywall: 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) + '@coinbase/onchainkit': + specifier: ^0.38.14 + version: 0.38.19(@farcaster/miniapp-sdk@0.2.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(@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.3)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76) + '@scure/base': + specifier: ^1.2.6 + 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.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.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.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@solana/sysvars@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)) '@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.6 + version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/wallet-standard-features': + specifier: ^1.3.0 + version: 1.3.0 + '@wagmi/connectors': + specifier: ^5.8.1 + version: 5.11.2(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(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.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@wallet-standard/app': + specifier: ^1.1.0 + version: 1.1.0 + '@wallet-standard/base': + specifier: ^1.1.0 + version: 1.1.0 + '@wallet-standard/features': + specifier: ^1.1.0 + version: 1.1.0 + '@x402/core': + specifier: workspace:* + version: link:../../core 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.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: + specifier: ^2.15.6 + version: 2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) x402: - specifier: workspace:^ - version: link:../x402 + specifier: workspace:* + version: link:../../legacy/x402 zod: specifier: ^3.24.2 version: 3.25.76 devDependencies: + '@craftamap/esbuild-plugin-html': + specifier: ^0.9.0 + version: 0.9.0(bufferutil@4.0.9)(esbuild@0.25.11)(utf-8-validate@5.0.10) '@eslint/js': specifier: ^9.24.0 - version: 9.34.0 + version: 9.38.0 '@types/node': specifier: ^22.13.4 - version: 22.18.0 + version: 22.18.12 + '@types/react': + specifier: ^19 + version: 19.2.2 + '@types/react-dom': + specifier: ^19 + version: 19.2.2(@types/react@19.2.2) '@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.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + buffer: + specifier: ^6.0.3 + version: 6.0.3 + esbuild: + specifier: ^0.25.4 + version: 0.25.11 eslint: specifier: ^9.24.0 - version: 9.34.0(jiti@1.21.7) + version: 9.38.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.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.38.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.4(eslint@9.38.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 + react-dom: + specifier: ^19.0.0 + 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.6)(typescript@5.9.3) tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.6 typescript: specifier: ^5.7.3 - version: 5.9.2 + version: 5.9.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.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6) 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.9.3)(vite@6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6)) 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.18.12)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.6) - packages/x402-next: + packages/legacy/coinbase-x402: 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) - '@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.2(@babel/core@7.28.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + specifier: ^1.29.0 + version: 1.38.4(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.3(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.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) x402: specifier: workspace:^ version: link:../x402 @@ -464,148 +516,698 @@ importers: devDependencies: '@eslint/js': specifier: ^9.24.0 - version: 9.34.0 + version: 9.38.0 '@types/node': specifier: ^22.13.4 - version: 22.18.0 + version: 22.18.12 '@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.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) eslint: specifier: ^9.24.0 - version: 9.34.0(jiti@1.21.7) + version: 9.38.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.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.38.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.4(eslint@9.38.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.6)(typescript@5.9.3) tsx: specifier: ^4.19.2 - version: 4.20.5 + version: 4.20.6 typescript: specifier: ^5.7.3 - version: 5.9.2 + version: 5.9.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.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6) 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.9.3)(vite@6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6)) 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.18.12)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.6) - site: + packages/legacy/x402: dependencies: - '@heroicons/react': - specifier: ^2.2.0 - version: 2.2.0(react@19.1.1) - '@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) - react: - specifier: ^19.0.0 - version: 19.1.1 - react-dom: - specifier: ^19.0.0 - version: 19.1.1(react@19.1.1) + '@scure/base': + specifier: ^1.2.6 + 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.3)(ws@8.18.3(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.3)(ws@8.18.3(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.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@solana/sysvars@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)) + '@solana/kit': + specifier: ^2.1.1 + version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(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.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/wallet-standard-features': + specifier: ^1.3.0 + version: 1.3.0 + '@wallet-standard/app': + specifier: ^1.1.0 + version: 1.1.0 + '@wallet-standard/base': + specifier: ^1.1.0 + version: 1.1.0 + '@wallet-standard/features': + specifier: ^1.1.0 + version: 1.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.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) 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) - 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) - x402-next: - specifier: workspace:* - version: link:../packages/x402-next + version: 2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + zod: + specifier: ^3.24.2 + version: 3.25.76 devDependencies: - '@eslint/eslintrc': - specifier: ^3 - version: 3.3.1 + '@coinbase/onchainkit': + specifier: ^0.38.14 + version: 0.38.19(@farcaster/miniapp-sdk@0.2.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(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.11)(utf-8-validate@5.0.10) '@eslint/js': specifier: ^9.24.0 - version: 9.34.0 - '@svgr/webpack': - specifier: ^8.1.0 - version: 8.1.0(typescript@5.9.2) + version: 9.38.0 '@types/node': - specifier: ^20 - version: 20.19.12 + specifier: ^22.13.4 + version: 22.18.12 '@types/react': specifier: ^19 - version: 19.1.12 + version: 19.2.2 '@types/react-dom': specifier: ^19 - version: 19.1.9(@types/react@19.1.12) + version: 19.2.2(@types/react@19.2.2) '@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.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + '@wagmi/connectors': + specifier: ^5.8.1 + version: 5.11.2(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@vercel/functions@2.2.13)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(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.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(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.11 eslint: specifier: ^9.24.0 - version: 9.34.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: 9.38.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.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.38.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) - postcss: - specifier: ^8 - version: 8.5.6 + version: 5.5.4(eslint@9.38.0(jiti@1.21.7))(prettier@3.5.2) prettier: specifier: 3.5.2 version: 3.5.2 - tailwindcss: - specifier: ^3.4.1 - version: 3.4.17 + react: + specifier: ^19.0.0 + version: 19.2.0 + react-dom: + specifier: ^19.0.0 + version: 19.2.0(react@19.2.0) + tsup: + specifier: ^8.4.0 + version: 8.5.0(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.6)(typescript@5.9.3) + tsx: + specifier: ^4.19.2 + version: 4.20.6 typescript: - specifier: ^5 - version: 5.9.2 - -packages: - - '@adraffy/ens-normalize@1.11.0': - resolution: {integrity: sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==} + specifier: ^5.7.3 + version: 5.9.3 + vite: + specifier: ^6.2.6 + version: 6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.9.3)(vite@6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6)) + vitest: + specifier: ^3.0.5 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.12)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.6) + + packages/legacy/x402-axios: + dependencies: + axios: + specifier: ^1.7.9 + version: 1.12.2 + viem: + specifier: ^2.21.26 + version: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + x402: + specifier: workspace:^ + version: link:../x402 + zod: + specifier: ^3.24.2 + version: 3.25.76 + devDependencies: + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 + '@types/node': + specifier: ^22.13.4 + version: 22.18.12 + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.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.6)(typescript@5.9.3) + tsx: + specifier: ^4.19.2 + version: 4.20.6 + typescript: + specifier: ^5.7.3 + version: 5.9.3 + vite: + specifier: ^6.2.6 + version: 6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.9.3)(vite@6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6)) + vitest: + specifier: ^3.0.5 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.12)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.6) + + packages/legacy/x402-express: + dependencies: + '@coinbase/cdp-sdk': + specifier: ^1.22.0 + version: 1.38.4(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/kit': + specifier: ^2.1.1 + version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(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.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + x402: + specifier: workspace:^ + version: link:../x402 + zod: + specifier: ^3.24.2 + version: 3.25.76 + devDependencies: + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 + '@types/express': + specifier: ^5.0.1 + version: 5.0.3 + '@types/node': + specifier: ^22.13.4 + version: 22.18.12 + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.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.6)(typescript@5.9.3) + tsx: + specifier: ^4.19.2 + version: 4.20.6 + typescript: + specifier: ^5.7.3 + version: 5.9.3 + vite: + specifier: ^6.2.6 + version: 6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.9.3)(vite@6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6)) + vitest: + specifier: ^3.0.5 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.12)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.6) + + packages/legacy/x402-fetch: + dependencies: + viem: + specifier: ^2.21.26 + version: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + x402: + specifier: workspace:^ + version: link:../x402 + zod: + specifier: ^3.24.2 + version: 3.25.76 + devDependencies: + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 + '@types/node': + specifier: ^22.13.4 + version: 22.18.12 + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.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.6)(typescript@5.9.3) + tsx: + specifier: ^4.19.2 + version: 4.20.6 + typescript: + specifier: ^5.7.3 + version: 5.9.3 + vite: + specifier: ^6.2.6 + version: 6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.9.3)(vite@6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6)) + vitest: + specifier: ^3.0.5 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.12)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.6) + + packages/legacy/x402-hono: + dependencies: + '@coinbase/cdp-sdk': + specifier: ^1.22.0 + version: 1.38.4(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/kit': + specifier: ^2.1.1 + version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + hono: + specifier: ^4.7.1 + version: 4.10.2 + viem: + specifier: ^2.21.26 + version: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + x402: + specifier: workspace:^ + version: link:../x402 + zod: + specifier: ^3.24.2 + version: 3.25.76 + devDependencies: + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 + '@types/node': + specifier: ^22.13.4 + version: 22.18.12 + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.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.6)(typescript@5.9.3) + tsx: + specifier: ^4.19.2 + version: 4.20.6 + typescript: + specifier: ^5.7.3 + version: 5.9.3 + vite: + specifier: ^6.2.6 + version: 6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.9.3)(vite@6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6)) + vitest: + specifier: ^3.0.5 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.12)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.6) + + packages/legacy/x402-next: + dependencies: + '@coinbase/cdp-sdk': + specifier: ^1.22.0 + version: 1.38.4(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/kit': + specifier: ^2.1.1 + version: 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + next: + specifier: ^15.0.0 + version: 15.5.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + viem: + specifier: ^2.21.26 + version: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + x402: + specifier: workspace:^ + version: link:../x402 + zod: + specifier: ^3.24.2 + version: 3.25.76 + devDependencies: + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 + '@types/node': + specifier: ^22.13.4 + version: 22.18.12 + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.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.6)(typescript@5.9.3) + tsx: + specifier: ^4.19.2 + version: 4.20.6 + typescript: + specifier: ^5.7.3 + version: 5.9.3 + vite: + specifier: ^6.2.6 + version: 6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.9.3)(vite@6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6)) + vitest: + specifier: ^3.0.5 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.12)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.6) + + packages/mechanisms/evm: + dependencies: + '@x402/core': + specifier: workspace:* + version: link:../../core + viem: + specifier: ^2.21.26 + version: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zod: + specifier: ^3.24.2 + version: 3.25.76 + devDependencies: + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 + '@types/node': + specifier: ^22.13.4 + version: 22.18.12 + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.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.6)(typescript@5.9.3) + tsx: + specifier: ^4.19.2 + version: 4.20.6 + typescript: + specifier: ^5.7.3 + version: 5.9.3 + vite: + specifier: ^6.2.6 + version: 6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.9.3)(vite@6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6)) + vitest: + specifier: ^3.0.5 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.12)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.6) + + packages/mechanisms/svm: + dependencies: + '@x402/core': + specifier: workspace:* + version: link:../../core + zod: + specifier: ^3.24.2 + version: 3.25.76 + devDependencies: + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 + '@types/node': + specifier: ^22.13.4 + version: 22.18.12 + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.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.6)(typescript@5.9.3) + tsx: + specifier: ^4.19.2 + version: 4.20.6 + typescript: + specifier: ^5.7.3 + version: 5.9.3 + vite: + specifier: ^6.2.6 + version: 6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.9.3)(vite@6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6)) + vitest: + specifier: ^3.0.5 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.12)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.6) + + site: + dependencies: + '@heroicons/react': + specifier: ^2.2.0 + version: 2.2.0(react@19.1.1) + '@vercel/functions': + specifier: ^2.2.8 + version: 2.2.13 + next: + specifier: 15.5.0 + version: 15.5.0(@babel/core@7.28.4)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + react: + specifier: 19.1.1 + version: 19.1.1 + react-dom: + specifier: 19.1.1 + version: 19.1.1(react@19.1.1) + viem: + specifier: ^2.21.26 + version: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + wagmi: + specifier: ^2.15.6 + version: 2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12))(zod@4.1.12) + x402: + specifier: workspace:* + version: link:../packages/legacy/x402 + x402-legacy: + specifier: npm:x402@0.1.2 + version: x402@0.1.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) + x402-next: + specifier: workspace:* + version: link:../packages/legacy/x402-next + devDependencies: + '@eslint/eslintrc': + specifier: ^3 + version: 3.3.1 + '@eslint/js': + specifier: ^9.24.0 + version: 9.38.0 + '@svgr/webpack': + specifier: ^8.1.0 + version: 8.1.0(typescript@5.9.3) + '@types/node': + specifier: ^20 + version: 20.19.23 + '@types/react': + specifier: ^19 + version: 19.2.2 + '@types/react-dom': + specifier: ^19 + version: 19.2.2(@types/react@19.2.2) + '@typescript-eslint/eslint-plugin': + specifier: ^8.29.1 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': + specifier: ^8.29.1 + version: 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + eslint: + specifier: ^9.24.0 + version: 9.38.0(jiti@1.21.7) + eslint-config-next: + specifier: 15.5.0 + version: 15.5.0(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsdoc: + specifier: ^50.6.9 + version: 50.8.0(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.6 + version: 5.5.4(eslint@9.38.0(jiti@1.21.7))(prettier@3.5.2) + postcss: + specifier: ^8 + version: 8.5.6 + prettier: + specifier: 3.5.2 + version: 3.5.2 + tailwindcss: + specifier: ^3.4.1 + version: 3.4.18(tsx@4.20.6) + typescript: + specifier: ^5 + version: 5.9.3 + +packages: + + '@adraffy/ens-normalize@1.11.1': + resolution: {integrity: sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==} '@alloc/quick-lru@5.2.0': resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - '@asamuzakjp/css-color@3.2.0': resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==} @@ -613,12 +1215,12 @@ 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.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': @@ -708,12 +1310,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 @@ -807,8 +1409,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 @@ -825,8 +1427,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 @@ -969,8 +1571,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 @@ -1047,8 +1649,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 @@ -1148,27 +1750,27 @@ 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': resolution: {integrity: sha512-IfVJPrDPhHfqXRDb89472hXkpvJuQQR7FDI9isLPHEqSYt/45whIoBxSPgZ0ssTt379VhQo4+87PWI1DoLSfAQ==} - '@coinbase/cdp-sdk@1.36.1': - resolution: {integrity: sha512-eL8PfuPMXdEKQ6v/AwlDbTpiLhmnwZPAxzJ2m90qL8oEQuYenALX8JqNKg0LBQ/sPM6c2vx109YvFx49g5vSYQ==} + '@coinbase/cdp-sdk@1.38.4': + resolution: {integrity: sha512-xVvfluaGt0NxNmjElP3C1yI6KnsGwihabdXj+qNtjjsSmd/Ha2V3gAiCyNrrYOqIORn4mpC2jgu2fUFEDaMpaw==} '@coinbase/onchainkit@0.38.19': resolution: {integrity: sha512-4uiujoTO5/8/dpWVZoTlBC7z0Y1N5fgBYDR6pKN/r6a8pX83ObUuOSGhSzJ8Xbu8NpPU6TXX+VuzLiwiLg/irg==} @@ -1222,11 +1824,11 @@ packages: peerDependencies: '@noble/ciphers': ^1.0.0 - '@emnapi/core@1.5.0': - resolution: {integrity: sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==} + '@emnapi/core@1.6.0': + resolution: {integrity: sha512-zq/ay+9fNIJJtJiZxdTnXS20PllcYMX3OE23ESc4HK/bdYu3cOWYVhsOhVnXALfU/uqJIxn5NBPd9z4v+SfoSg==} - '@emnapi/runtime@1.5.0': - resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==} + '@emnapi/runtime@1.6.0': + resolution: {integrity: sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA==} '@emnapi/wasi-threads@1.1.0': resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} @@ -1235,198 +1837,198 @@ packages: 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.11': + resolution: {integrity: sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==} 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.11': + resolution: {integrity: sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.25.9': - resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==} + '@esbuild/android-arm@0.25.11': + resolution: {integrity: sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.25.9': - resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==} + '@esbuild/android-x64@0.25.11': + resolution: {integrity: sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.25.9': - resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==} + '@esbuild/darwin-arm64@0.25.11': + resolution: {integrity: sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==} 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.11': + resolution: {integrity: sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==} 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.11': + resolution: {integrity: sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.9': - resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==} + '@esbuild/freebsd-x64@0.25.11': + resolution: {integrity: sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.25.9': - resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==} + '@esbuild/linux-arm64@0.25.11': + resolution: {integrity: sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.25.9': - resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==} + '@esbuild/linux-arm@0.25.11': + resolution: {integrity: sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==} 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.11': + resolution: {integrity: sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.25.9': - resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==} + '@esbuild/linux-loong64@0.25.11': + resolution: {integrity: sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.25.9': - resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==} + '@esbuild/linux-mips64el@0.25.11': + resolution: {integrity: sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.25.9': - resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==} + '@esbuild/linux-ppc64@0.25.11': + resolution: {integrity: sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.25.9': - resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==} + '@esbuild/linux-riscv64@0.25.11': + resolution: {integrity: sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==} 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.11': + resolution: {integrity: sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.25.9': - resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==} + '@esbuild/linux-x64@0.25.11': + resolution: {integrity: sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==} 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.11': + resolution: {integrity: sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.9': - resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==} + '@esbuild/netbsd-x64@0.25.11': + resolution: {integrity: sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.9': - resolution: {integrity: sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==} + '@esbuild/openbsd-arm64@0.25.11': + resolution: {integrity: sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.9': - resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==} + '@esbuild/openbsd-x64@0.25.11': + resolution: {integrity: sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.9': - resolution: {integrity: sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==} + '@esbuild/openharmony-arm64@0.25.11': + resolution: {integrity: sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.25.9': - resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==} + '@esbuild/sunos-x64@0.25.11': + resolution: {integrity: sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==} 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.11': + resolution: {integrity: sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.25.9': - resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==} + '@esbuild/win32-ia32@0.25.11': + resolution: {integrity: sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==} 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.11': + resolution: {integrity: sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==} 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.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 - '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} 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.21.1': + resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} 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/config-helpers@0.4.1': + resolution: {integrity: sha512-csZAzkNhsgwb0I/UAV6/RGFTbiakPCf0ZrGmrIxQpYvGZ00PhTkSnyKNolphgIvmnJeGw6rcGVEXfTzUnFuEvw==} 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.16.0': + resolution: {integrity: sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==} 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.38.0': + resolution: {integrity: sha512-UZ1VpFvXf9J06YG9xQBdnzU+kthors6KjhMAl6f4gH4usHyh31rUf2DLGInT8RFYIReYXNSydgPY0V2LuWgl7A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/object-schema@2.1.6': - resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} 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.4.0': + resolution: {integrity: sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ethereumjs/common@3.2.0': @@ -1445,20 +2047,20 @@ packages: resolution: {integrity: sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==} engines: {node: '>=14'} - '@farcaster/frame-sdk@0.1.9': - resolution: {integrity: sha512-r5cAKgHn4w8Q1jaCi84uKqItfNRd6h8Lk0YyQaz5kMoEIeJ4C0gXPpyqKPYP2TVDFuvaexg2KvzCO2CQdygWyQ==} + '@farcaster/frame-sdk@0.1.12': + resolution: {integrity: sha512-qlikvkxsrsvKGutr3PM3Yvsuni2Fku15aPagrCyHZWbYAJrZ4mRJM6u9S8eLAXMMnYd9gJ9yor6COYgmZMBOgQ==} engines: {node: '>=22.11.0'} - '@farcaster/miniapp-core@0.3.8': - resolution: {integrity: sha512-LaRG1L3lxHqo5pP/E2CX9hNqusR0C8hX3QTV2+hzmQJz6IGvmSpH6Q9ivlLyDfbdqokiMFo5Y3Z1EX1zBHMEQQ==} + '@farcaster/miniapp-core@0.4.1': + resolution: {integrity: sha512-20FxHTRToYUKx7CQ8PvIy9OoQ6XjdmF1pRMS7dsj37qdqjVDeEkYoK8yXwnoReZoJRcYwIg8P3i6V8bTWNR5mg==} - '@farcaster/miniapp-sdk@0.1.9': - resolution: {integrity: sha512-hn0dlIy0JP2Hx6PgKcn9bjYwyPS/SQgYJ/a0qjzG8ZsDfUdjsMPf3yI/jicBipTml/UUoKcbqXM68fsrsbNMKA==} + '@farcaster/miniapp-sdk@0.2.1': + resolution: {integrity: sha512-2SnDeOtDdlN1lGQt7UyH2jkrZRQDOkmhcrlzNWazYChyPh9XfV8+9fMS+Lr/E2pEws9Q40Xl9POrCzdpUC19lg==} - '@farcaster/miniapp-wagmi-connector@1.0.0': - resolution: {integrity: sha512-vMRZbekUUctnAUvBFhNoEsJlujRRdxop94fDy5LrKiRR9ax0wtp8gCvLYO+LpaP2PtGs0HFpRwlHNDJWvBR8bg==} + '@farcaster/miniapp-wagmi-connector@1.1.0': + resolution: {integrity: sha512-gf0nDx9nNJ6hJXbFBCgiTitb0eEqBvCU/njcyTXf7ebZhT0pzOrarOod2dkeisU5Py+WWjFyOVcqmeo4G3IvDA==} peerDependencies: - '@farcaster/miniapp-sdk': ^0.1.0 + '@farcaster/miniapp-sdk': ^0.2.0 '@wagmi/core': ^2.14.1 viem: ^2.21.55 @@ -1467,6 +2069,11 @@ packages: peerDependencies: typescript: 5.8.3 + '@farcaster/quick-auth@0.0.8': + resolution: {integrity: sha512-NRIq1BcbcQCC6xBF5owfckkY00xKQVpqhpLNl5rICVpl0xeDsiVbkenIrHaUuyjtCK2W28YVc2ZCFRyz9ERHKg==} + peerDependencies: + typescript: 5.8.3 + '@gemini-wallet/core@0.2.0': resolution: {integrity: sha512-vv9aozWnKrrPWQ3vIFcWk7yta4hQW1Ie0fsNNPeXnjAxkbXr2hqMagEptLuMxpEP2W3mnRu05VDNKzcvAuuZDw==} peerDependencies: @@ -1482,8 +2089,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.19.5': + resolution: {integrity: sha512-iBuhh+uaaggeAuf+TftcjZyWh2GEgZcVGXkNtskLVoWaXhnJtC5HLHrU8W1KHDoucqO1MswwglmkWLFyiDn4WQ==} engines: {node: '>=18.14.1'} peerDependencies: hono: ^4 @@ -1504,124 +2111,128 @@ packages: 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] @@ -1633,6 +2244,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'} @@ -1640,8 +2254,8 @@ 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==} '@lit-labs/ssr-dom-shim@1.4.0': resolution: {integrity: sha512-ficsEARKnmmW5njugNYKipTm4SFnbik7CXtoencDZzmzo/dQ+2Q0bgkzJuoJP20Aj0F+izzJjOqsnkd6F/o1bw==} @@ -1691,8 +2305,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: '*' @@ -1700,18 +2317,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.7.0': - resolution: {integrity: sha512-IamqpZF8Lr4WeXJ84fD+Sy+v1Zo05SYuMPHHBrZWpzVbnHAmXQpL4ckn9s5dfA+zylp3WGypaBPb6SBZdOhuNQ==} + '@metamask/utils@11.8.1': + resolution: {integrity: sha512-DIbsNUyqWLFgqJlZxi1OOCMYvI23GqFCvNJAtzv8/WXWzJfnJnvp1M24j7VvUe3URBi3S86UgQ7+7aWU9p/cnQ==} engines: {node: ^18.18 || ^20.14 || >=22} '@metamask/utils@5.0.2': @@ -1729,56 +2346,107 @@ packages: '@napi-rs/wasm-runtime@0.2.12': resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} - '@next/env@15.5.2': - resolution: {integrity: sha512-Qe06ew4zt12LeO6N7j8/nULSOe3fMXE4dM6xgpBQNvdzyK1sv5y4oAP3bq4LamrvGCZtmRYnW8URFCeX5nFgGg==} + '@next/env@15.5.0': + resolution: {integrity: sha512-sDaprBAfzCQiOgo2pO+LhnV0Wt2wBgartjrr+dpcTORYVnnXD0gwhHhiiyIih9hQbq+JnbqH4odgcFWhqCGidw==} + + '@next/env@15.5.6': + resolution: {integrity: sha512-3qBGRW+sCGzgbpc5TS1a0p7eNxnOarGVQhZxfvTdnV0gFI61lX7QNtQ4V1TSREctXzYn5NetbUsLvyqwLFJM6Q==} - '@next/eslint-plugin-next@15.1.7': - resolution: {integrity: sha512-kRP7RjSxfTO13NE317ek3mSGzoZlI33nc/i5hs1KaWpK+egs85xg0DJ4p32QEiHnR0mVjuUfhRIun7awqfL7pQ==} + '@next/eslint-plugin-next@15.5.0': + resolution: {integrity: sha512-+k83U/fST66eQBjTltX2T9qUYd43ntAe+NZ5qeZVTQyTiFiHvTLtkpLKug4AnZAtuI/lwz5tl/4QDJymjVkybg==} + + '@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-arm64@15.5.2': - resolution: {integrity: sha512-8bGt577BXGSd4iqFygmzIfTYizHb0LGWqH+qgIF/2EDxS5JsSdERJKA8WgwDyNBZgTIIA4D8qUtoQHmxIIquoQ==} + '@next/swc-darwin-arm64@15.5.6': + resolution: {integrity: sha512-ES3nRz7N+L5Umz4KoGfZ4XX6gwHplwPhioVRc25+QNsDa7RtUF/z8wJcbuQ2Tffm5RZwuN2A063eapoJ1u4nPg==} 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.5.0': + resolution: {integrity: sha512-s2Nk6ec+pmYmAb/utawuURy7uvyYKDk+TRE5aqLRsdnj3AhwC9IKUBmhfnLmY/+P+DnwqpeXEFIKe9tlG0p6CA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@next/swc-darwin-x64@15.5.6': + resolution: {integrity: sha512-JIGcytAyk9LQp2/nuVZPAtj8uaJ/zZhsKOASTjxDug0SPU9LAM3wy6nPU735M1OqacR4U20LHVF5v5Wnl9ptTA==} 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.5.0': + resolution: {integrity: sha512-mGlPJMZReU4yP5fSHjOxiTYvZmwPSWn/eF/dcg21pwfmiUCKS1amFvf1F1RkLHPIMPfocxLViNWFvkvDB14Isg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-arm64-gnu@15.5.6': + resolution: {integrity: sha512-qvz4SVKQ0P3/Im9zcS2RmfFL/UCQnsJKJwQSkissbngnB/12c6bZTCB0gHTexz1s6d/mD0+egPKXAIRFVS7hQg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@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-arm64-musl@15.5.2': - resolution: {integrity: sha512-s6N8k8dF9YGc5T01UPQ08yxsK6fUow5gG1/axWc1HVVBYQBgOjca4oUZF7s4p+kwhkB1bDSGR8QznWrFZ/Rt5g==} + '@next/swc-linux-arm64-musl@15.5.6': + resolution: {integrity: sha512-FsbGVw3SJz1hZlvnWD+T6GFgV9/NYDeLTNQB2MXoPN5u9VA9OEDy6fJEfePfsUKAhJufFbZLgp0cPxMuV6SV0w==} 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.5.0': + resolution: {integrity: sha512-zPisT+obYypM/l6EZ0yRkK3LEuoZqHaSoYKj+5jiD9ESHwdr6QhnabnNxYkdy34uCigNlWIaCbjFmQ8FY5AlxA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-linux-x64-gnu@15.5.6': + resolution: {integrity: sha512-3QnHGFWlnvAgyxFxt2Ny8PTpXtQD7kVEeaFat5oPAHHI192WKYB+VIKZijtHLGdBBvc16tiAkPTDmQNOQ0dyrA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-linux-x64-musl@15.5.0': + resolution: {integrity: sha512-+t3+7GoU9IYmk+N+FHKBNFdahaReoAktdOpXHFIPOU1ixxtdge26NgQEEkJkCw2dHT9UwwK5zw4mAsURw4E8jA==} 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.5.6': + resolution: {integrity: sha512-OsGX148sL+TqMK9YFaPFPoIaJKbFJJxFzkXZljIgA9hjMjdruKht6xDCEv1HLtlLNfkx3c5w2GLKhj7veBQizQ==} 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.5.0': + resolution: {integrity: sha512-d8MrXKh0A+c9DLiy1BUFwtg3Hu90Lucj3k6iKTUdPOv42Ve2UiIG8HYi3UAb8kFVluXxEfdpCoPPCSODk5fDcw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-arm64-msvc@15.5.6': + resolution: {integrity: sha512-ONOMrqWxdzXDJNh2n60H6gGyKed42Ieu6UTVPZteXpuKbLZTH4G4eBMsr5qWgOBA+s7F+uB4OJbZnrkEDnZ5Fg==} 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.5.0': + resolution: {integrity: sha512-Fe1tGHxOWEyQjmygWkkXSwhFcTJuimrNu52JEuwItrKJVV4iRjbWp9I7zZjwqtiNnQmxoEvoisn8wueFLrNpvQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@next/swc-win32-x64-msvc@15.5.6': + resolution: {integrity: sha512-pxK4VIjFRx1MY92UycLOOw7dTdvccWsNETQ0kDHkBlcFH1GrTLUjSiHU1ohrznnux6TqRHgv5oflhfIWZwVROQ==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -1883,116 +2551,121 @@ 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.52.5': + resolution: {integrity: sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.50.0': - resolution: {integrity: sha512-2O73dR4Dc9bp+wSYhviP6sDziurB5/HCym7xILKifWdE9UsOe2FtNcM+I4xZjKrfLJnq5UR8k9riB87gauiQtw==} + '@rollup/rollup-android-arm64@4.52.5': + resolution: {integrity: sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.50.0': - resolution: {integrity: sha512-vwSXQN8T4sKf1RHr1F0s98Pf8UPz7pS6P3LG9NSmuw0TVh7EmaE+5Ny7hJOZ0M2yuTctEsHHRTMi2wuHkdS6Hg==} + '@rollup/rollup-darwin-arm64@4.52.5': + resolution: {integrity: sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.50.0': - resolution: {integrity: sha512-cQp/WG8HE7BCGyFVuzUg0FNmupxC+EPZEwWu2FCGGw5WDT1o2/YlENbm5e9SMvfDFR6FRhVCBePLqj0o8MN7Vw==} + '@rollup/rollup-darwin-x64@4.52.5': + resolution: {integrity: sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.50.0': - resolution: {integrity: sha512-UR1uTJFU/p801DvvBbtDD7z9mQL8J80xB0bR7DqW7UGQHRm/OaKzp4is7sQSdbt2pjjSS72eAtRh43hNduTnnQ==} + '@rollup/rollup-freebsd-arm64@4.52.5': + resolution: {integrity: sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==} 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.52.5': + resolution: {integrity: sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.50.0': - resolution: {integrity: sha512-u72Mzc6jyJwKjJbZZcIYmd9bumJu7KNmHYdue43vT1rXPm2rITwmPWF0mmPzLm9/vJWxIRbao/jrQmxTO0Sm9w==} + '@rollup/rollup-linux-arm-gnueabihf@4.52.5': + resolution: {integrity: sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==} 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.52.5': + resolution: {integrity: sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.50.0': - resolution: {integrity: sha512-1EhkSvUQXJsIhk4msxP5nNAUWoB4MFDHhtc4gAYvnqoHlaL9V3F37pNHabndawsfy/Tp7BPiy/aSa6XBYbaD1g==} + '@rollup/rollup-linux-arm64-gnu@4.52.5': + resolution: {integrity: sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==} 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.52.5': + resolution: {integrity: sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.50.0': - resolution: {integrity: sha512-BGYSwJdMP0hT5CCmljuSNx7+k+0upweM2M4YGfFBjnFSZMHOLYR0gEEj/dxyYJ6Zc6AiSeaBY8dWOa11GF/ppQ==} + '@rollup/rollup-linux-loong64-gnu@4.52.5': + resolution: {integrity: sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.50.0': - resolution: {integrity: sha512-I1gSMzkVe1KzAxKAroCJL30hA4DqSi+wGc5gviD0y3IL/VkvcnAqwBf4RHXHyvH66YVHxpKO8ojrgc4SrWAnLg==} + '@rollup/rollup-linux-ppc64-gnu@4.52.5': + resolution: {integrity: sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.50.0': - resolution: {integrity: sha512-bSbWlY3jZo7molh4tc5dKfeSxkqnf48UsLqYbUhnkdnfgZjgufLS/NTA8PcP/dnvct5CCdNkABJ56CbclMRYCA==} + '@rollup/rollup-linux-riscv64-gnu@4.52.5': + resolution: {integrity: sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.50.0': - resolution: {integrity: sha512-LSXSGumSURzEQLT2e4sFqFOv3LWZsEF8FK7AAv9zHZNDdMnUPYH3t8ZlaeYYZyTXnsob3htwTKeWtBIkPV27iQ==} + '@rollup/rollup-linux-riscv64-musl@4.52.5': + resolution: {integrity: sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.50.0': - resolution: {integrity: sha512-CxRKyakfDrsLXiCyucVfVWVoaPA4oFSpPpDwlMcDFQvrv3XY6KEzMtMZrA+e/goC8xxp2WSOxHQubP8fPmmjOQ==} + '@rollup/rollup-linux-s390x-gnu@4.52.5': + resolution: {integrity: sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==} 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.52.5': + resolution: {integrity: sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==} 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.52.5': + resolution: {integrity: sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==} cpu: [x64] os: [linux] - '@rollup/rollup-openharmony-arm64@4.50.0': - resolution: {integrity: sha512-PZkNLPfvXeIOgJWA804zjSFH7fARBBCpCXxgkGDRjjAhRLOR8o0IGS01ykh5GYfod4c2yiiREuDM8iZ+pVsT+Q==} + '@rollup/rollup-openharmony-arm64@4.52.5': + resolution: {integrity: sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.50.0': - resolution: {integrity: sha512-q7cIIdFvWQoaCbLDUyUc8YfR3Jh2xx3unO8Dn6/TTogKjfwrax9SyfmGGK6cQhKtjePI7jRfd7iRYcxYs93esg==} + '@rollup/rollup-win32-arm64-msvc@4.52.5': + resolution: {integrity: sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==} 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.52.5': + resolution: {integrity: sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.50.0': - resolution: {integrity: sha512-xMmiWRR8sp72Zqwjgtf3QbZfF1wdh8X2ABu3EaozvZcyHJeU0r+XAnXdKgs4cCAp6ORoYoCygipYP1mjmbjrsg==} + '@rollup/rollup-win32-x64-gnu@4.52.5': + resolution: {integrity: sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.52.5': + resolution: {integrity: sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==} 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.14.0': + resolution: {integrity: sha512-WJFej426qe4RWOm9MMtP4V3CV4AucXolQty+GRgAWLgQXmpCuwzs7hEpxxhSc/znXUSxum9d/P/32MW0FlAAlA==} '@safe-global/safe-apps-provider@0.18.6': resolution: {integrity: sha512-4LhMmjPWlIO8TTDC2AwLk44XKXaK6hfBTWyljDm0HQ6TWlOEijVWNrt2s3OCVMSxlXAcEzYfqyu1daHZooTC2Q==} @@ -2036,6 +2709,11 @@ packages: peerDependencies: '@solana/kit': ^2.1.0 + '@solana-program/system@0.8.1': + resolution: {integrity: sha512-71U9Mzdpw8HQtfgfJSL5xKZbLMRnza2Llsfk7gGnmg2waqK+o8MMH4YNma8xXS1UmOBptXIiNvoZ3p7cmOVktg==} + peerDependencies: + '@solana/kit': ^3.0 + '@solana-program/token-2022@0.4.2': resolution: {integrity: sha512-zIpR5t4s9qEU3hZKupzIBxJ6nUV5/UVyIT400tu9vT1HMs5JHxaTTsb5GUhYjiiTvNwU0MQavbwc4Dl29L0Xvw==} peerDependencies: @@ -2047,47 +2725,62 @@ packages: peerDependencies: '@solana/kit': ^2.1.0 + '@solana-program/token@0.6.0': + resolution: {integrity: sha512-omkZh4Tt9rre4wzWHNOhOEHyenXQku3xyc/UrKvShexA/Qlhza67q7uRwmwEDUs4QqoDBidSZPooOmepnA/jig==} + peerDependencies: + '@solana/kit': ^3.0 + '@solana/accounts@2.3.0': resolution: {integrity: sha512-QgQTj404Z6PXNOyzaOpSzjgMOuGwG8vC66jSDB+3zHaRcEPRVRd2sVSrd1U6sHtnV3aiaS6YyDuPQMheg4K2jw==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/accounts@3.0.3': + resolution: {integrity: sha512-KqlePrlZaHXfu8YQTCxN204ZuVm9o68CCcUr6l27MG2cuRUtEM1Ta0iR8JFkRUAEfZJC4Cu0ZDjK/v49loXjZQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/addresses@2.3.0': resolution: {integrity: sha512-ypTNkY2ZaRFpHLnHAgaW8a83N0/WoqdFvCqf4CQmnMdFsZSdC7qOwcbd7YzdaQn9dy+P2hybewzB+KP7LutxGA==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/addresses@3.0.3': + resolution: {integrity: sha512-AuMwKhJI89ANqiuJ/fawcwxNKkSeHH9CApZd2xelQQLS7X8uxAOovpcmEgiObQuiVP944s9ScGUT62Bdul9qYg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/assertions@2.3.0': resolution: {integrity: sha512-Ekoet3khNg3XFLN7MIz8W31wPQISpKUGDGTylLptI+JjCDWx3PIa88xjEMqFo02WJ8sBj2NLV64Xg1sBcsHjZQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' - '@solana/buffer-layout-utils@0.2.0': - resolution: {integrity: sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==} - engines: {node: '>= 10'} + '@solana/assertions@3.0.3': + resolution: {integrity: sha512-2qspxdbWp2y62dfCIlqeWQr4g+hE8FYSSwcaP6itwMwGRb8393yDGCJfI/znuzJh6m/XVWhMHIgFgsBwnevCmg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' '@solana/buffer-layout@4.0.1': resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} engines: {node: '>=5.10'} - '@solana/codecs-core@2.0.0-rc.1': - resolution: {integrity: sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==} - peerDependencies: - typescript: '>=5' - '@solana/codecs-core@2.3.0': resolution: {integrity: sha512-oG+VZzN6YhBHIoSKgS5ESM9VIGzhWjEHEGNPSibiDTxFhsFWxNaz8LbMDPjBUE69r9wmdGLkrQ+wVPbnJcZPvw==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' - '@solana/codecs-data-structures@2.0.0-rc.1': - resolution: {integrity: sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==} + '@solana/codecs-core@3.0.3': + resolution: {integrity: sha512-emKykJ3h1DmnDOY29Uv9eJXP8E/FHzvlUBJ6te+5EbKdFjj7vdlKYPfDxOI6iGdXTY+YC/ELtbNBh6QwF2uEDQ==} + engines: {node: '>=20.18.0'} peerDependencies: - typescript: '>=5' + typescript: '>=5.3.3' '@solana/codecs-data-structures@2.3.0': resolution: {integrity: sha512-qvU5LE5DqEdYMYgELRHv+HMOx73sSoV1ZZkwIrclwUmwTbTaH8QAJURBj0RhQ/zCne7VuLLOZFFGv6jGigWhSw==} @@ -2095,10 +2788,11 @@ packages: peerDependencies: typescript: '>=5.3.3' - '@solana/codecs-numbers@2.0.0-rc.1': - resolution: {integrity: sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==} + '@solana/codecs-data-structures@3.0.3': + resolution: {integrity: sha512-R15cLp8riJvToXziW8lP6AMSwsztGhEnwgyGmll32Mo0Yjq+hduW2/fJrA/TJs6tA/OgTzMQjlxgk009EqZHCw==} + engines: {node: '>=20.18.0'} peerDependencies: - typescript: '>=5' + typescript: '>=5.3.3' '@solana/codecs-numbers@2.3.0': resolution: {integrity: sha512-jFvvwKJKffvG7Iz9dmN51OGB7JBcy2CJ6Xf3NqD/VP90xak66m/Lg48T01u5IQ/hc15mChVHiBm+HHuOFDUrQg==} @@ -2106,11 +2800,11 @@ packages: peerDependencies: typescript: '>=5.3.3' - '@solana/codecs-strings@2.0.0-rc.1': - resolution: {integrity: sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==} + '@solana/codecs-numbers@3.0.3': + resolution: {integrity: sha512-pfXkH9J0glrM8qj6389GAn30+cJOxzXLR2FsPOHCUMXrqLhGjMMZAWhsQkpOQ37SGc/7EiQsT/gmyGC7gxHqJQ==} + engines: {node: '>=20.18.0'} peerDependencies: - fastestsmallesttextencoderdecoder: ^1.0.22 - typescript: '>=5' + typescript: '>=5.3.3' '@solana/codecs-strings@2.3.0': resolution: {integrity: sha512-y5pSBYwzVziXu521hh+VxqUtp0hYGTl1eWGoc1W+8mdvBdC1kTqm/X7aYQw33J42hw03JjryvYOvmGgk3Qz/Ug==} @@ -2119,10 +2813,12 @@ packages: fastestsmallesttextencoderdecoder: ^1.0.22 typescript: '>=5.3.3' - '@solana/codecs@2.0.0-rc.1': - resolution: {integrity: sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==} + '@solana/codecs-strings@3.0.3': + resolution: {integrity: sha512-VHBXnnTVtcQ1j+7Vrz+qSYo38no+jiHRdGnhFspRXEHNJbllzwKqgBE7YN3qoIXH+MKxgJUcwO5KHmdzf8Wn2A==} + engines: {node: '>=20.18.0'} peerDependencies: - typescript: '>=5' + fastestsmallesttextencoderdecoder: ^1.0.22 + typescript: '>=5.3.3' '@solana/codecs@2.3.0': resolution: {integrity: sha512-JVqGPkzoeyU262hJGdH64kNLH0M+Oew2CIPOa/9tR3++q2pEd4jU2Rxdfye9sd0Ce3XJrR5AIa8ZfbyQXzjh+g==} @@ -2130,11 +2826,11 @@ packages: peerDependencies: typescript: '>=5.3.3' - '@solana/errors@2.0.0-rc.1': - resolution: {integrity: sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==} - hasBin: true + '@solana/codecs@3.0.3': + resolution: {integrity: sha512-GOHwTlIQsCoJx9Ryr6cEf0FHKAQ7pY4aO4xgncAftrv0lveTQ1rPP2inQ1QT0gJllsIa8nwbfXAADs9nNJxQDA==} + engines: {node: '>=20.18.0'} peerDependencies: - typescript: '>=5' + typescript: '>=5.3.3' '@solana/errors@2.3.0': resolution: {integrity: sha512-66RI9MAbwYV0UtP7kGcTBVLxJgUxoZGm8Fbc0ah+lGiAw17Gugco6+9GrJCV83VyF2mDWyYnYM9qdI3yjgpnaQ==} @@ -2143,46 +2839,90 @@ packages: peerDependencies: typescript: '>=5.3.3' + '@solana/errors@3.0.3': + resolution: {integrity: sha512-1l84xJlHNva6io62PcYfUamwWlc0eM95nHgCrKX0g0cLoC6D6QHYPCEbEVkR+C5UtP9JDgyQM8MFiv+Ei5tO9Q==} + engines: {node: '>=20.18.0'} + hasBin: true + peerDependencies: + typescript: '>=5.3.3' + '@solana/fast-stable-stringify@2.3.0': resolution: {integrity: sha512-KfJPrMEieUg6D3hfQACoPy0ukrAV8Kio883llt/8chPEG3FVTX9z/Zuf4O01a15xZmBbmQ7toil2Dp0sxMJSxw==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/fast-stable-stringify@3.0.3': + resolution: {integrity: sha512-ED0pxB6lSEYvg+vOd5hcuQrgzEDnOrURFgp1ZOY+lQhJkQU6xo+P829NcJZQVP1rdU2/YQPAKJKEseyfe9VMIw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/functional@2.3.0': resolution: {integrity: sha512-AgsPh3W3tE+nK3eEw/W9qiSfTGwLYEvl0rWaxHht/lRcuDVwfKRzeSa5G79eioWFFqr+pTtoCr3D3OLkwKz02Q==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/functional@3.0.3': + resolution: {integrity: sha512-2qX1kKANn8995vOOh5S9AmF4ItGZcfbny0w28Eqy8AFh+GMnSDN4gqpmV2LvxBI9HibXZptGH3RVOMk82h1Mpw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/instruction-plans@3.0.3': + resolution: {integrity: sha512-eqoaPtWtmLTTpdvbt4BZF5H6FIlJtXi9H7qLOM1dLYonkOX2Ncezx5NDCZ9tMb2qxVMF4IocYsQnNSnMfjQF1w==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/instructions@2.3.0': resolution: {integrity: sha512-PLMsmaIKu7hEAzyElrk2T7JJx4D+9eRwebhFZpy2PXziNSmFF929eRHKUsKqBFM3cYR1Yy3m6roBZfA+bGE/oQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/instructions@3.0.3': + resolution: {integrity: sha512-4csIi8YUDb5j/J+gDzmYtOvq7ZWLbCxj4t0xKn+fPrBk/FD2pK29KVT3Fu7j4Lh1/ojunQUP9X4NHwUexY3PnA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/keys@2.3.0': resolution: {integrity: sha512-ZVVdga79pNH+2pVcm6fr2sWz9HTwfopDVhYb0Lh3dh+WBmJjwkabXEIHey2rUES7NjFa/G7sV8lrUn/v8LDCCQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/keys@3.0.3': + resolution: {integrity: sha512-tp8oK9tMadtSIc4vF4aXXWkPd4oU5XPW8nf28NgrGDWGt25fUHIydKjkf2hPtMt9i1WfRyQZ33B5P3dnsNqcPQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/kit@2.3.0': resolution: {integrity: sha512-sb6PgwoW2LjE5oTFu4lhlS/cGt/NB3YrShEyx7JgWFWysfgLdJnhwWThgwy/4HjNsmtMrQGWVls0yVBHcMvlMQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/kit@3.0.3': + resolution: {integrity: sha512-CEEhCDmkvztd1zbgADsEQhmj9GyWOOGeW1hZD+gtwbBSF5YN1uofS/pex5MIh/VIqKRj+A2UnYWI1V+9+q/lyQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/nominal-types@2.3.0': resolution: {integrity: sha512-uKlMnlP4PWW5UTXlhKM8lcgIaNj8dvd8xO4Y9l+FVvh9RvW2TO0GwUO6JCo7JBzCB0PSqRJdWWaQ8pu1Ti/OkA==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' - '@solana/options@2.0.0-rc.1': - resolution: {integrity: sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==} + '@solana/nominal-types@3.0.3': + resolution: {integrity: sha512-aZavCiexeUAoMHRQg4s1AHkH3wscbOb70diyfjhwZVgFz1uUsFez7csPp9tNFkNolnadVb2gky7yBk3IImQJ6A==} + engines: {node: '>=20.18.0'} peerDependencies: - typescript: '>=5' + typescript: '>=5.3.3' '@solana/options@2.3.0': resolution: {integrity: sha512-PPnnZBRCWWoZQ11exPxf//DRzN2C6AoFsDI/u2AsQfYih434/7Kp4XLpfOMT/XESi+gdBMFNNfbES5zg3wAIkw==} @@ -2190,50 +2930,105 @@ packages: peerDependencies: typescript: '>=5.3.3' + '@solana/options@3.0.3': + resolution: {integrity: sha512-jarsmnQ63RN0JPC5j9sgUat07NrL9PC71XU7pUItd6LOHtu4+wJMio3l5mT0DHVfkfbFLL6iI6+QmXSVhTNF3g==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/programs@2.3.0': resolution: {integrity: sha512-UXKujV71VCI5uPs+cFdwxybtHZAIZyQkqDiDnmK+DawtOO9mBn4Nimdb/6RjR2CXT78mzO9ZCZ3qfyX+ydcB7w==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/programs@3.0.3': + resolution: {integrity: sha512-JZlVE3/AeSNDuH3aEzCZoDu8GTXkMpGXxf93zXLzbxfxhiQ/kHrReN4XE/JWZ/uGWbaFZGR5B3UtdN2QsoZL7w==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/promises@2.3.0': resolution: {integrity: sha512-GjVgutZKXVuojd9rWy1PuLnfcRfqsaCm7InCiZc8bqmJpoghlyluweNc7ml9Y5yQn1P2IOyzh9+p/77vIyNybQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/promises@3.0.3': + resolution: {integrity: sha512-K+UflGBVxj30XQMHTylHHZJdKH5QG3oj5k2s42GrZ/Wbu72oapVJySMBgpK45+p90t8/LEqV6rRPyTXlet9J+Q==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/rpc-api@2.3.0': resolution: {integrity: sha512-UUdiRfWoyYhJL9PPvFeJr4aJ554ob2jXcpn4vKmRVn9ire0sCbpQKYx6K8eEKHZWXKrDW8IDspgTl0gT/aJWVg==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/rpc-api@3.0.3': + resolution: {integrity: sha512-Yym9/Ama62OY69rAZgbOCAy1QlqaWAyb0VlqFuwSaZV1pkFCCFSwWEJEsiN1n8pb2ZP+RtwNvmYixvWizx9yvA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/rpc-parsed-types@2.3.0': resolution: {integrity: sha512-B5pHzyEIbBJf9KHej+zdr5ZNAdSvu7WLU2lOUPh81KHdHQs6dEb310LGxcpCc7HVE8IEdO20AbckewDiAN6OCg==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/rpc-parsed-types@3.0.3': + resolution: {integrity: sha512-/koM05IM2fU91kYDQxXil3VBNlOfcP+gXE0js1sdGz8KonGuLsF61CiKB5xt6u1KEXhRyDdXYLjf63JarL4Ozg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/rpc-spec-types@2.3.0': resolution: {integrity: sha512-xQsb65lahjr8Wc9dMtP7xa0ZmDS8dOE2ncYjlvfyw/h4mpdXTUdrSMi6RtFwX33/rGuztQ7Hwaid5xLNSLvsFQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/rpc-spec-types@3.0.3': + resolution: {integrity: sha512-A6Jt8SRRetnN3CeGAvGJxigA9zYRslGgWcSjueAZGvPX+MesFxEUjSWZCfl+FogVFvwkqfkgQZQbPAGZQFJQ6Q==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/rpc-spec@2.3.0': resolution: {integrity: sha512-fA2LMX4BMixCrNB2n6T83AvjZ3oUQTu7qyPLyt8gHQaoEAXs8k6GZmu6iYcr+FboQCjUmRPgMaABbcr9j2J9Sw==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/rpc-spec@3.0.3': + resolution: {integrity: sha512-MZn5/8BebB6MQ4Gstw6zyfWsFAZYAyLzMK+AUf/rSfT8tPmWiJ/mcxnxqOXvFup/l6D67U8pyGpIoFqwCeZqqA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/rpc-subscriptions-api@2.3.0': resolution: {integrity: sha512-9mCjVbum2Hg9KGX3LKsrI5Xs0KX390lS+Z8qB80bxhar6MJPugqIPH8uRgLhCW9GN3JprAfjRNl7our8CPvsPQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' - '@solana/rpc-subscriptions-channel-websocket@2.3.0': - resolution: {integrity: sha512-2oL6ceFwejIgeWzbNiUHI2tZZnaOxNTSerszcin7wYQwijxtpVgUHiuItM/Y70DQmH9sKhmikQp+dqeGalaJxw==} + '@solana/rpc-subscriptions-api@3.0.3': + resolution: {integrity: sha512-MGgVK3PUS15qsjuhimpzGZrKD/CTTvS0mAlQ0Jw84zsr1RJVdQJK/F0igu07BVd172eTZL8d90NoAQ3dahW5pA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-subscriptions-channel-websocket@2.3.0': + resolution: {integrity: sha512-2oL6ceFwejIgeWzbNiUHI2tZZnaOxNTSerszcin7wYQwijxtpVgUHiuItM/Y70DQmH9sKhmikQp+dqeGalaJxw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + ws: ^8.18.0 + + '@solana/rpc-subscriptions-channel-websocket@3.0.3': + resolution: {integrity: sha512-zUzUlb8Cwnw+SHlsLrSqyBRtOJKGc+FvSNJo/vWAkLShoV0wUDMPv7VvhTngJx3B/3ANfrOZ4i08i9QfYPAvpQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' @@ -2245,59 +3040,83 @@ packages: peerDependencies: typescript: '>=5.3.3' + '@solana/rpc-subscriptions-spec@3.0.3': + resolution: {integrity: sha512-9KpQ32OBJWS85mn6q3gkM0AjQe1LKYlMU7gpJRrla/lvXxNLhI95tz5K6StctpUreVmRWTVkNamHE69uUQyY8A==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/rpc-subscriptions@2.3.0': resolution: {integrity: sha512-Uyr10nZKGVzvCOqwCZgwYrzuoDyUdwtgQRefh13pXIrdo4wYjVmoLykH49Omt6abwStB0a4UL5gX9V4mFdDJZg==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/rpc-subscriptions@3.0.3': + resolution: {integrity: sha512-LRvz6NaqvtsYFd32KwZ+rwYQ9XCs+DWjV8BvBLsJpt9/NWSuHf/7Sy/vvP6qtKxut692H/TMvHnC4iulg0WmiQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/rpc-transformers@2.3.0': resolution: {integrity: sha512-UuHYK3XEpo9nMXdjyGKkPCOr7WsZsxs7zLYDO1A5ELH3P3JoehvrDegYRAGzBS2VKsfApZ86ZpJToP0K3PhmMA==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/rpc-transformers@3.0.3': + resolution: {integrity: sha512-lzdaZM/dG3s19Tsk4mkJA5JBoS1eX9DnD7z62gkDwrwJDkDBzkAJT9aLcsYFfTmwTfIp6uU2UPgGYc97i1wezw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/rpc-transport-http@2.3.0': resolution: {integrity: sha512-HFKydmxGw8nAF5N+S0NLnPBDCe5oMDtI2RAmW8DMqP4U3Zxt2XWhvV1SNkAldT5tF0U1vP+is6fHxyhk4xqEvg==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/rpc-transport-http@3.0.3': + resolution: {integrity: sha512-bIXFwr2LR5A97Z46dI661MJPbHnPfcShBjFzOS/8Rnr8P4ho3j/9EUtjDrsqoxGJT3SLWj5OlyXAlaDAvVTOUQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/rpc-types@2.3.0': resolution: {integrity: sha512-O09YX2hED2QUyGxrMOxQ9GzH1LlEwwZWu69QbL4oYmIf6P5dzEEHcqRY6L1LsDVqc/dzAdEs/E1FaPrcIaIIPw==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' - '@solana/rpc@2.3.0': - resolution: {integrity: sha512-ZWN76iNQAOCpYC7yKfb3UNLIMZf603JckLKOOLTHuy9MZnTN8XV6uwvDFhf42XvhglgUjGCEnbUqWtxQ9pa/pQ==} + '@solana/rpc-types@3.0.3': + resolution: {integrity: sha512-petWQ5xSny9UfmC3Qp2owyhNU0w9SyBww4+v7tSVyXMcCC9v6j/XsqTeimH1S0qQUllnv0/FY83ohFaxofmZ6Q==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' - '@solana/signers@2.3.0': - resolution: {integrity: sha512-OSv6fGr/MFRx6J+ZChQMRqKNPGGmdjkqarKkRzkwmv7v8quWsIRnJT5EV8tBy3LI4DLO/A8vKiNSPzvm1TdaiQ==} + '@solana/rpc@2.3.0': + resolution: {integrity: sha512-ZWN76iNQAOCpYC7yKfb3UNLIMZf603JckLKOOLTHuy9MZnTN8XV6uwvDFhf42XvhglgUjGCEnbUqWtxQ9pa/pQ==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' - '@solana/spl-token-group@0.0.7': - resolution: {integrity: sha512-V1N/iX7Cr7H0uazWUT2uk27TMqlqedpXHRqqAbVO2gvmJyT0E0ummMEAVQeXZ05ZhQ/xF39DLSdBp90XebWEug==} - engines: {node: '>=16'} + '@solana/rpc@3.0.3': + resolution: {integrity: sha512-3oukAaLK78GegkKcm6iNmRnO4mFeNz+BMvA8T56oizoBNKiRVEq/6DFzVX/LkmZ+wvD601pAB3uCdrTPcC0YKQ==} + engines: {node: '>=20.18.0'} peerDependencies: - '@solana/web3.js': ^1.95.3 + typescript: '>=5.3.3' - '@solana/spl-token-metadata@0.1.6': - resolution: {integrity: sha512-7sMt1rsm/zQOQcUWllQX9mD2O6KhSAtY1hFR2hfFwgqfFWzSY9E9GDvFVNYUI1F0iQKcm6HmePU9QbKRXTEBiA==} - engines: {node: '>=16'} + '@solana/signers@2.3.0': + resolution: {integrity: sha512-OSv6fGr/MFRx6J+ZChQMRqKNPGGmdjkqarKkRzkwmv7v8quWsIRnJT5EV8tBy3LI4DLO/A8vKiNSPzvm1TdaiQ==} + engines: {node: '>=20.18.0'} peerDependencies: - '@solana/web3.js': ^1.95.3 + typescript: '>=5.3.3' - '@solana/spl-token@0.4.14': - resolution: {integrity: sha512-u09zr96UBpX4U685MnvQsNzlvw9TiY005hk1vJmJr7gMJldoPG1eYU5/wNEyOA5lkMLiR/gOi9SFD4MefOYEsA==} - engines: {node: '>=16'} + '@solana/signers@3.0.3': + resolution: {integrity: sha512-UwCd/uPYTZiwd283JKVyOWLLN5sIgMBqGDyUmNU3vo9hcmXKv5ZGm/9TvwMY2z35sXWuIOcj7etxJ8OoWc/ObQ==} + engines: {node: '>=20.18.0'} peerDependencies: - '@solana/web3.js': ^1.95.5 + typescript: '>=5.3.3' '@solana/subscribable@2.3.0': resolution: {integrity: sha512-DkgohEDbMkdTWiKAoatY02Njr56WXx9e/dKKfmne8/Ad6/2llUIrax78nCdlvZW9quXMaXPTxZvdQqo9N669Og==} @@ -2305,30 +3124,64 @@ packages: peerDependencies: typescript: '>=5.3.3' + '@solana/subscribable@3.0.3': + resolution: {integrity: sha512-FJ27LKGHLQ5GGttPvTOLQDLrrOZEgvaJhB7yYaHAhPk25+p+erBaQpjePhfkMyUbL1FQbxn1SUJmS6jUuaPjlQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/sysvars@2.3.0': resolution: {integrity: sha512-LvjADZrpZ+CnhlHqfI5cmsRzX9Rpyb1Ox2dMHnbsRNzeKAMhu9w4ZBIaeTdO322zsTr509G1B+k2ABD3whvUBA==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/sysvars@3.0.3': + resolution: {integrity: sha512-GnHew+QeKCs2f9ow+20swEJMH4mDfJA/QhtPgOPTYQx/z69J4IieYJ7fZenSHnA//lJ45fVdNdmy1trypvPLBQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/transaction-confirmation@2.3.0': resolution: {integrity: sha512-UiEuiHCfAAZEKdfne/XljFNJbsKAe701UQHKXEInYzIgBjRbvaeYZlBmkkqtxwcasgBTOmEaEKT44J14N9VZDw==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/transaction-confirmation@3.0.3': + resolution: {integrity: sha512-dXx0OLtR95LMuARgi2dDQlL1QYmk56DOou5q9wKymmeV3JTvfDExeWXnOgjRBBq/dEfj4ugN1aZuTaS18UirFw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/transaction-messages@2.3.0': resolution: {integrity: sha512-bgqvWuy3MqKS5JdNLH649q+ngiyOu5rGS3DizSnWwYUd76RxZl1kN6CoqHSrrMzFMvis6sck/yPGG3wqrMlAww==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/transaction-messages@3.0.3': + resolution: {integrity: sha512-s+6NWRnBhnnjFWV4x2tzBzoWa6e5LiIxIvJlWwVQBFkc8fMGY04w7jkFh0PM08t/QFKeXBEWkyBDa/TFYdkWug==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@solana/transactions@2.3.0': resolution: {integrity: sha512-LnTvdi8QnrQtuEZor5Msje61sDpPstTVwKg4y81tNxDhiyomjuvnSNLAq6QsB9gIxUqbNzPZgOG9IU4I4/Uaug==} engines: {node: '>=20.18.0'} peerDependencies: typescript: '>=5.3.3' + '@solana/transactions@3.0.3': + resolution: {integrity: sha512-iMX+n9j4ON7H1nKlWEbMqMOpKYC6yVGxKKmWHT1KdLRG7v+03I4DnDeFoI+Zmw56FA+7Bbne8jwwX60Q1vk/MQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/wallet-standard-features@1.3.0': + resolution: {integrity: sha512-ZhpZtD+4VArf6RPitsVExvgkF+nGghd1rzPjd97GmBximpnt1rsUxMOEyoIEuH3XBxPyNB6Us7ha7RHWQR+abg==} + engines: {node: '>=16'} + '@solana/web3.js@1.98.4': resolution: {integrity: sha512-vv9lfnvjUsRiq//+j5pBdXig0IQdtzA0BRZ3bXEP4KaIyF1CcaydWqgyzQgfZMNIsWNWmG+AUHwPy4AHOD6gpw==} @@ -2416,11 +3269,11 @@ packages: '@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.90.5': + resolution: {integrity: sha512-wLamYp7FaDq6ZnNehypKI5fNvxHPfTYylE0m/ZpuuzJfJqhR5Pxg9gvGBHZx4n7J+V5Rg5mZxHHTlv25Zt5u+w==} - '@tanstack/react-query@5.85.9': - resolution: {integrity: sha512-2T5zgSpcOZXGkH/UObIbIkGmUPQqZqn7esVQFXLOze622h4spgWf5jmvrqAo9dnI13/hyMcNsF1jsoDcb59nJQ==} + '@tanstack/react-query@5.90.5': + resolution: {integrity: sha512-pN+8UWpxZkEJ/Rnnj2v2Sxpx1WFlaa9L6a4UO89p6tTQbeo+m0MS8oYDjbggrR8QcTyjKoYWKS3xJQGr3ExT8Q==} peerDependencies: react: ^18 || ^19 @@ -2428,14 +3281,14 @@ 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/body-parser@1.19.6': resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} - '@types/chai@5.2.2': - resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} @@ -2449,8 +3302,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.1.0': + resolution: {integrity: sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA==} '@types/express@5.0.3': resolution: {integrity: sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw==} @@ -2476,11 +3329,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.23': + resolution: {integrity: sha512-yIdlVVVHXpmqRhtyovZAcSy0MiPcYWGkoO4CGe/+jpP0hmNuihm4XhHbADpK++MsiLHP5MVlv+bcgdF99kSiFQ==} - '@types/node@22.18.0': - resolution: {integrity: sha512-m5ObIqwsUp6BZzyiy4RdZpzWGub9bqLJMvZDD0QMXhxjqMHMENlj+SqF5QxoUwaQNFe+8kz8XM8ZQhqkQPTgMQ==} + '@types/node@22.18.12': + resolution: {integrity: sha512-BICHQ67iqxQGFSzfCFTT7MRQ5XcBjG5aeKh5Ok38UBbPe5fxTyE+aHFxwVrGyr8GNlqFMLKD1D3P2K/1ks8tog==} '@types/qs@6.14.0': resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} @@ -2488,19 +3341,22 @@ 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.2.2': + resolution: {integrity: sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==} peerDependencies: - '@types/react': ^19.0.0 + '@types/react': ^19.2.0 - '@types/react@19.1.12': - resolution: {integrity: sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==} + '@types/react@19.2.2': + resolution: {integrity: sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==} '@types/send@0.17.5': resolution: {integrity: sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==} - '@types/serve-static@1.15.8': - resolution: {integrity: sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==} + '@types/send@1.2.0': + resolution: {integrity: sha512-zBF6vZJn1IaMpg3xUF25VK3gd3l8zwE0ZLRX7dsQyQi+jp4E8mMDJNGDYnYse+bQhYwWERTxVwHpi3dMOq7RKQ==} + + '@types/serve-static@1.15.9': + resolution: {integrity: sha512-dOTIuqpWLyl3BBXU3maNQsS4A3zuuoYRNIvYSxxhebPfXg2mzWQEPne/nlJ37yOse6uGgR386uTpdsx4D0QZWA==} '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} @@ -2514,63 +3370,63 @@ 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.46.2': + resolution: {integrity: sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.42.0 + '@typescript-eslint/parser': ^8.46.2 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.42.0': - resolution: {integrity: sha512-r1XG74QgShUgXph1BYseJ+KZd17bKQib/yF3SR+demvytiRXrwd12Blnz5eYGm8tXaeRdd4x88MlfwldHoudGg==} + '@typescript-eslint/parser@8.46.2': + resolution: {integrity: sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==} 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.42.0': - resolution: {integrity: sha512-vfVpLHAhbPjilrabtOSNcUDmBboQNrJUiNAGoImkZKnMjs2TIcWG33s4Ds0wY3/50aZmTMqJa6PiwkwezaAklg==} + '@typescript-eslint/project-service@8.46.2': + resolution: {integrity: sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.42.0': - resolution: {integrity: sha512-51+x9o78NBAVgQzOPd17DkNTnIzJ8T/O2dmMBLoK9qbY0Gm52XJcdJcCl18ExBMiHo6jPMErUQWUv5RLE51zJw==} + '@typescript-eslint/scope-manager@8.46.2': + resolution: {integrity: sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==} 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.46.2': + resolution: {integrity: sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.42.0': - resolution: {integrity: sha512-9KChw92sbPTYVFw3JLRH1ockhyR3zqqn9lQXol3/YbI6jVxzWoGcT3AsAW0mu1MY0gYtsXnUGV/AKpkAj5tVlQ==} + '@typescript-eslint/type-utils@8.46.2': + resolution: {integrity: sha512-HbPM4LbaAAt/DjxXaG9yiS9brOOz6fabal4uvUmaUYe6l3K1phQDMQKBRUrr06BQkxkvIZVVHttqiybM9nJsLA==} 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.42.0': - resolution: {integrity: sha512-LdtAWMiFmbRLNP7JNeY0SqEtJvGMYSzfiWBSmx+VSZ1CH+1zyl8Mmw1TT39OrtsRvIYShjJWzTDMPWZJCpwBlw==} + '@typescript-eslint/types@8.46.2': + resolution: {integrity: sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==} 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.46.2': + resolution: {integrity: sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.42.0': - resolution: {integrity: sha512-JnIzu7H3RH5BrKC4NoZqRfmjqCIS1u3hGZltDYJgkVdqAezl4L9d1ZLw+36huCujtSBSAirGINF/S4UxOcR+/g==} + '@typescript-eslint/utils@8.46.2': + resolution: {integrity: sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg==} 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.42.0': - resolution: {integrity: sha512-3WbiuzoEowaEn8RSnhJBrxSwX8ULYE9CXaPepS2C2W3NSA5NNIvBaslpBSBElPq0UGr0xVJlXFWOAKIkyylydQ==} + '@typescript-eslint/visitor-keys@8.46.2': + resolution: {integrity: sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@unrs/resolver-binding-android-arm-eabi@1.11.1': @@ -2710,18 +3566,28 @@ packages: '@vitest/utils@3.2.4': resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} - '@wagmi/connectors@5.9.9': - resolution: {integrity: sha512-6+eqU7P2OtxU2PkIw6kHojfYYUJykYG2K5rSkzVh29RDCAjhJqGEZW5f1b8kV5rUBORip1NpST8QTBNi96JHGQ==} + '@wagmi/connectors@5.11.2': + resolution: {integrity: sha512-OkiElOI8xXGPDZE5UdG6NgDT3laSkEh9llX1DDapUnfnKecK3Tr/HUf5YzgwDhEoox8mdxp+8ZCjtnTKz56SdA==} + peerDependencies: + '@wagmi/core': 2.21.2 + typescript: '>=5.0.4' + viem: 2.x + peerDependenciesMeta: + typescript: + optional: true + + '@wagmi/connectors@6.1.0': + resolution: {integrity: sha512-MnpJHEABUIsajNxLc6br0LiqJvoFZbavQ6yG+mQb7Xlb3Hmm3IRjH5NU1g2zw5PCTRd3BFQLjwniLdwDnUPYNw==} peerDependencies: - '@wagmi/core': 2.20.3 + '@wagmi/core': 2.22.1 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.22.1': + resolution: {integrity: sha512-cG/xwQWsBEcKgRTkQVhH29cbpbs/TdcUJVFXCyri3ZknxhMyGv0YEjTcrNpRgt2SaswL1KrvslSNYKKo+5YEAg==} peerDependencies: '@tanstack/query-core': '>=5.0.0' typescript: '>=5.0.4' @@ -2732,6 +3598,18 @@ packages: typescript: optional: true + '@wallet-standard/app@1.1.0': + resolution: {integrity: sha512-3CijvrO9utx598kjr45hTbbeeykQrQfKmSnxeWOgU25TOEpvcipD/bYDQWIqUv1Oc6KK4YStokSMu/FBNecGUQ==} + engines: {node: '>=16'} + + '@wallet-standard/base@1.1.0': + resolution: {integrity: sha512-DJDQhjKmSNVLKWItoKThJS+CsJQjR9AOBOirBVT1F9YpRyC9oYHE+ZnSf8y8bxUphtKqdQMPVQ2mHohYdRvDVQ==} + engines: {node: '>=16'} + + '@wallet-standard/features@1.1.0': + resolution: {integrity: sha512-hiEivWNztx73s+7iLxsuD1sOJ28xtRix58W7Xnz4XzzA/pF0+aicnWgjOdA10doVDEDZdUuZCIIqG96SFNlDUg==} + engines: {node: '>=16'} + '@walletconnect/core@2.21.0': resolution: {integrity: sha512-o6R7Ua4myxR8aRUAJ1z3gT9nM+jd2B2mfamu6arzy1Cc6vi10fIwFWb6vg3bC8xJ6o9H3n/cN5TOW3aA9Y1XVw==} engines: {node: '>=18'} @@ -2853,6 +3731,17 @@ packages: 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 + zod: + optional: true + accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -2882,16 +3771,16 @@ 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: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - 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: @@ -2975,8 +3864,8 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axe-core@4.10.3: - resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==} + axe-core@4.11.0: + resolution: {integrity: sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ==} engines: {node: '>=4'} axios-retry@4.5.0: @@ -2984,8 +3873,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==} @@ -3018,23 +3907,17 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + baseline-browser-mapping@2.8.19: + resolution: {integrity: sha512-zoKGUdu6vb2jd3YOq0nnhEDQVbPcHhco3UImJrv5dSkvxTc2pl2WjOPsjZXDwPDSl5eghIMuY3R6J9NDKF3KcQ==} + hasBin: true + big.js@6.2.2: resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} - bigint-buffer@1.1.5: - resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} - engines: {node: '>= 10.0.0'} - - bignumber.js@9.3.1: - resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} - binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} - bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - bn.js@5.2.2: resolution: {integrity: sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==} @@ -3061,8 +3944,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.27.0: + resolution: {integrity: sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -3121,8 +4004,8 @@ 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.30001751: + resolution: {integrity: sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==} chai@5.3.3: resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} @@ -3132,8 +4015,8 @@ packages: 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: @@ -3172,13 +4055,6 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - color-string@1.9.1: - resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} - - color@4.2.3: - resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} - engines: {node: '>=12.5.0'} - combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} @@ -3186,14 +4062,14 @@ packages: comlink@4.4.2: resolution: {integrity: sha512-OxGdvBmJuNKSCMO4NTl1L47VRp6xn2wG4F/2hYzB6tiCb709otOxtEYCSvK80PtjODfXXZu8ds+Nw5kVCjqd2g==} - commander@12.1.0: - resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} - engines: {node: '>=18'} - commander@14.0.0: resolution: {integrity: sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==} engines: {node: '>=20'} + commander@14.0.1: + resolution: {integrity: sha512-2JkV3gUZUVrbNA+1sjBOYLsMZ5cEEl8GTFP2a4AVz5hvasAMCQ1D2l2le/cX+pV4N6ZU17zjUahLpIXRrnWL8A==} + engines: {node: '>=20'} + commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -3240,8 +4116,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.46.0: + resolution: {integrity: sha512-p9hObIIEENxSV8xIu+V68JjSeARg6UVMG5mR+JEUguG3sI6MsiS1njz2jHmyJDvA+8jX/sytkBHup6kxhM9law==} core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -3349,8 +4225,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: '*' @@ -3358,8 +4234,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: '*' @@ -3427,8 +4303,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.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} didyoumean@1.2.2: @@ -3470,15 +4346,15 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - eciesjs@0.4.15: - resolution: {integrity: sha512-r6kEJXDKecVOCj2nLMuXK/FCPeurW33+3JRpfXVbjLja3XUYFfD9I/JBreH6sUyzcm3G/YQboBjMla6poKeSdA==} + eciesjs@0.4.16: + resolution: {integrity: sha512-dS5cbA9rA2VR4Ybuvhg6jvdmp46ubLn3E+px8cG/35aEDNclrqoCjg6mt0HYZ/M+OoESS3jSkCrqk1kWAEhWAw==} engines: {bun: '>=1', deno: '>=2', node: '>=16'} 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.239: + resolution: {integrity: sha512-1y5w0Zsq39MSPmEjHjbizvhYoTaulVtivpxkp5q5kaPmQtsK6/2nvAzGRxNMS9DoYySp9PkW0MAQDwU1m764mg==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -3515,8 +4391,8 @@ packages: resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} - 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==} @@ -3562,8 +4438,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.11: + resolution: {integrity: sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==} engines: {node: '>=18'} hasBin: true @@ -3578,8 +4454,8 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - eslint-config-next@15.1.7: - resolution: {integrity: sha512-zXoMnYUIy3XHaAoOhrcYkT9UQWvXqWju2K7NNsmb5wd/7XESDwof61eUdW4QhERr3eJ9Ko/vnXqIrj8kk/drYw==} + eslint-config-next@15.5.0: + resolution: {integrity: sha512-Yl4hlOdBqstAuHnlBfx2RimBzWQwysM2SJNu5EzYVa2qS2ItPs7lgxL0sJJDudEx5ZZHfWPZ/6U8+FtDFWs7/w==} peerDependencies: eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 typescript: '>=3.3.1' @@ -3684,8 +4560,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.38.0: + resolution: {integrity: sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -3813,9 +4689,6 @@ packages: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} - file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -3890,6 +4763,10 @@ packages: functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -3910,8 +4787,8 @@ packages: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} - get-tsconfig@4.10.1: - resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} + get-tsconfig@4.13.0: + resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} @@ -3982,8 +4859,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.10.2: + resolution: {integrity: sha512-p6fyzl+mQo6uhESLxbF5WlBOAJMDh36PljwlKtP5V1v09NxlqGru3ShK+4wKhSuhuYf8qxMmrivHOa/M7q0sMg==} engines: {node: '>=16.9.0'} html-encoding-sniffer@4.0.0: @@ -4063,9 +4940,6 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - 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==} engines: {node: '>= 0.4'} @@ -4116,8 +4990,8 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - is-generator-function@1.1.0: - resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} engines: {node: '>= 0.4'} is-glob@4.0.3: @@ -4260,11 +5134,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'} @@ -4382,8 +5251,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.19: + resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} @@ -4461,6 +5330,9 @@ packages: 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==} @@ -4475,8 +5347,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.3.4: + resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} hasBin: true @@ -4487,8 +5359,29 @@ 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.5.0: + resolution: {integrity: sha512-N1lp9Hatw3a9XLt0307lGB4uTKsXDhyOKQo7uYMzX4i0nF/c27grcGXkLdb7VcT8QPYLBa8ouIyEoUQJ2OyeNQ==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.51.1 + 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 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + + next@15.5.6: + resolution: {integrity: sha512-zTxsnI3LQo3c9HSdSf91O1jMNsEzIXDShXd4wVdg9y5shwLqBXi4ZtUUJyB86KGVSJLZx0PFONvO54aheGX8QQ==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} hasBin: true peerDependencies: @@ -4530,11 +5423,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.26: + resolution: {integrity: sha512-S2M9YimhSjBSvYnlr5/+umAnPHE++ODwt5e2Ij6FoX45HA/s4vHdkDx1eax2pAPeAOqu4s9b7ppahsyEFdVqQA==} normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} @@ -4543,8 +5436,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==} @@ -4598,6 +5491,12 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + openapi-fetch@0.13.8: + resolution: {integrity: sha512-yJ4QKRyNxE44baQ9mY5+r/kAzZ8yXMemtNAOFwOzRXJscdjSxxzWSNlyBAr+o5JjkUw9Lc3W7OIoca0cY3PYnQ==} + + openapi-typescript-helpers@0.0.15: + resolution: {integrity: sha512-opyTPaunsklCBpTK8JGef6mfPhLSnyy5a0IN9vKtx3+4aExf+KxEqYwIy3hqkedXIB97u357uLMJsOnm3GVjsw==} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -4630,8 +5529,16 @@ packages: typescript: optional: true - ox@0.9.3: - resolution: {integrity: sha512-KzyJP+fPV4uhuuqrTZyok4DC7vFzi7HLUFiUNEmpbyh59htKWkOC98IONC1zgXJPbHAhQgqs6B0Z6StCGhmQvg==} + ox@0.9.12: + resolution: {integrity: sha512-esyA5WXfFhlxpgzoVIEreRaasqqv95sjFpk3L4Me4RWk8bgBDe+J4wO3RZ5ikYmJ2Bbjyv+jKgxyaOzX6JpHPA==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + ox@0.9.6: + resolution: {integrity: sha512-8SuCbHPvv2eZLYXrNmC0EC12rdzXQLdhnOMlHDW2wiCPLxBrOOJwX5L5E61by+UjTPOryqQiRSnjIKCI+GykKg==} peerDependencies: typescript: '>=5.4.0' peerDependenciesMeta: @@ -4759,6 +5666,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'} @@ -4769,24 +5696,12 @@ 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 - postcss-load-config@4.0.2: - resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} - engines: {node: '>= 14'} - peerDependencies: - postcss: '>=8.0.9' - ts-node: '>=9.0.0' - peerDependenciesMeta: - postcss: - optional: true - ts-node: - optional: true - postcss-load-config@6.0.1: resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} engines: {node: '>= 18'} @@ -4829,8 +5744,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==} @@ -4911,6 +5826,11 @@ packages: peerDependencies: react: ^19.1.1 + react-dom@19.2.0: + resolution: {integrity: sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==} + peerDependencies: + react: ^19.2.0 + react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} @@ -4918,6 +5838,10 @@ packages: resolution: {integrity: sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==} engines: {node: '>=0.10.0'} + react@19.2.0: + resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==} + engines: {node: '>=0.10.0'} + read-cache@1.0.0: resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} @@ -4944,8 +5868,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: @@ -4955,15 +5879,15 @@ 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 require-directory@2.1.1: @@ -4984,8 +5908,8 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - resolve@1.22.10: - resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} engines: {node: '>= 0.4'} hasBin: true @@ -4997,13 +5921,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.52.5: + resolution: {integrity: sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - 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==} @@ -5043,12 +5967,15 @@ packages: scheduler@0.26.0: resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} engines: {node: '>=10'} hasBin: true @@ -5083,8 +6010,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: @@ -5118,9 +6045,6 @@ 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==} - snake-case@3.0.4: resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} @@ -5171,8 +6095,8 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} - std-env@3.9.0: - resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} stop-iteration-iterator@1.1.0: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} @@ -5232,8 +6156,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: @@ -5244,8 +6168,8 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - strip-literal@3.0.0: - resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} + strip-literal@3.1.0: + resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} styled-jsx@5.1.6: resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} @@ -5299,8 +6223,8 @@ packages: tailwind-merge@2.6.0: resolution: {integrity: sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==} - tailwindcss@3.4.17: - resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} + tailwindcss@3.4.18: + resolution: {integrity: sha512-6A2rnmW5xZMdw11LYjhcI5846rt9pbLSabY5XPxo+XWdxwZaFEn47Go4NzFiHu9sNNmr/kXivP1vStfvMaK1GQ==} engines: {node: '>=14.0.0'} hasBin: true @@ -5323,8 +6247,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: @@ -5335,8 +6259,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: @@ -5346,8 +6270,8 @@ packages: resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} hasBin: true - 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: @@ -5423,43 +6347,43 @@ packages: typescript: optional: true - tsx@4.20.5: - resolution: {integrity: sha512-+wKjMNU9w/EaQayHXb7WA7ZaHY6hN8WgfvHNQ3t1PnU91/7O8TcTnIhCDYTZwnt8JsO9IBqZ30Ln1r7pPF52Aw==} + tsx@4.20.6: + resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==} 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 type-check@0.4.0: @@ -5486,8 +6410,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.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} hasBin: true @@ -5507,8 +6431,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==} @@ -5518,12 +6442,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'} unpipe@1.0.0: @@ -5533,8 +6457,8 @@ packages: unrs-resolver@1.11.1: resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} - unstorage@1.17.0: - resolution: {integrity: sha512-l9Z7lBiwtNp8ZmcoZ/dmPkFXFdtEdZtTZafCSnEIj3YvtkXeGAtL2rN8MQFy/0cs4eOLpuRJMp9ivdug7TCvww==} + unstorage@1.17.1: + resolution: {integrity: sha512-KKGwRTT0iVBCErKemkJCLs7JdxNVfqTPc/85ae1XES0+bsHbc/sFBfVi5kJp156cc51BHinIH2l3k0EZ24vOBQ==} peerDependencies: '@azure/app-configuration': ^1.8.0 '@azure/cosmos': ^4.2.0 @@ -5548,7 +6472,7 @@ packages: '@planetscale/database': ^1.19.0 '@upstash/redis': ^1.34.3 '@vercel/blob': '>=0.27.1' - '@vercel/functions': ^2.2.12 + '@vercel/functions': ^2.2.12 || ^3.0.0 '@vercel/kv': ^1.0.1 aws4fetch: ^1.0.20 db0: '>=0.2.1' @@ -5595,8 +6519,8 @@ packages: uploadthing: optional: true - update-browserslist-db@1.1.3: - resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + update-browserslist-db@1.1.4: + resolution: {integrity: sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -5660,8 +6584,8 @@ packages: typescript: optional: true - viem@2.37.3: - resolution: {integrity: sha512-hwoZqkFSy13GCFzIftgfIH8hNENvdlcHIvtLt73w91tL6rKmZjQisXWTahi1Vn5of8/JQ1FBKfwUus3YkDXwbw==} + viem@2.38.3: + resolution: {integrity: sha512-By2TutLv07iNHHtWqHHzjGipevYsfGqT7KQbGEmqLco1qTJxKnvBbSviqiu6/v/9REV6Q/FpmIxf2Z7/l5AbcQ==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -5681,8 +6605,8 @@ packages: vite: optional: true - vite@6.3.5: - resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==} + vite@6.4.1: + resolution: {integrity: sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: @@ -5753,8 +6677,8 @@ packages: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} - wagmi@2.16.9: - resolution: {integrity: sha512-5NbjvuNNhT0t0lQsDD5otQqZ5RZBM1UhInHoBq/Lpnr6xLLa8AWxYqHg5oZtGCdiUNltys11iBOS6z4mLepIqw==} + wagmi@2.18.2: + resolution: {integrity: sha512-9jFip+0ZfjMBxT72m02MZD2+VmQQ/UmqZhHl+98N9HEqXLn765fIu45QPV85DAnQqIHD81gvY3vTvfWt16A5yQ==} peerDependencies: '@tanstack/react-query': '>=5.0.0' react: '>=18' @@ -5915,11 +6839,6 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yaml@2.8.1: - resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} - engines: {node: '>= 14.6'} - hasBin: true - yargs-parser@18.1.3: resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} engines: {node: '>=6'} @@ -5938,6 +6857,9 @@ packages: zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zod@4.1.12: + resolution: {integrity: sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==} + zustand@5.0.0: resolution: {integrity: sha512-LE+VcmbartOPM+auOjCCLQOsQ05zUTp8RkgwRzefUk+2jISdMMFnxvyTjA4YNWr5ZGXYbVsEMZosttuxUBkojQ==} engines: {node: '>=12.20.0'} @@ -5974,17 +6896,30 @@ packages: use-sync-external-store: optional: true + zustand@5.0.8: + resolution: {integrity: sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw==} + 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': {} + '@adraffy/ens-normalize@1.11.1': {} '@alloc/quick-lru@5.2.0': {} - '@ampproject/remapping@2.3.0': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 - '@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) @@ -5999,22 +6934,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 @@ -6023,52 +6958,52 @@ 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.4 + browserslist: 4.27.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.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 + resolve: 1.22.11 transitivePeerDependencies: - supports-color @@ -6076,55 +7011,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 @@ -6137,649 +7072,739 @@ 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@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) - core-js-compat: 3.45.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) + core-js-compat: 3.46.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.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.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)': + '@base-org/account@1.1.1(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(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 + eventemitter3: 5.0.1 + idb-keyval: 6.2.1 + ox: 0.6.9(typescript@5.9.3)(zod@3.25.76) + preact: 10.24.2 + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.3(@types/react@19.2.2)(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.2.2)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@4.1.12)': + 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.3)(zod@4.1.12) + preact: 10.24.2 + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + zustand: 5.0.3(@types/react@19.2.2)(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.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@3.25.76)': 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) + ox: 0.6.9(typescript@5.9.3)(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)) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.3(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)) + transitivePeerDependencies: + - '@types/react' + - bufferutil + - immer + - react + - typescript + - use-sync-external-store + - utf-8-validate + - zod + + '@coinbase/cdp-sdk@1.38.4(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana-program/system': 0.8.1(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + '@solana-program/token': 0.6.0(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) + abitype: 1.0.6(typescript@5.9.3)(zod@3.25.76) + 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.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zod: 3.25.76 transitivePeerDependencies: + - bufferutil + - debug + - encoding + - fastestsmallesttextencoderdecoder + - typescript + - utf-8-validate + - ws + + '@coinbase/onchainkit@0.38.19(@farcaster/miniapp-sdk@0.2.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(@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.3)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@farcaster/frame-sdk': 0.1.12(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@farcaster/miniapp-wagmi-connector': 1.1.0(@farcaster/miniapp-sdk@0.2.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@tanstack/react-query': 5.90.5(react@19.1.1) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + 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) + tailwind-merge: 2.6.0 + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: 2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(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/functions' + - '@vercel/kv' + - aws4fetch - bufferutil + - db0 + - encoding - immer - - react + - ioredis + - supports-color - typescript + - uploadthing - 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)': - 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 - 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 - transitivePeerDependencies: - - bufferutil - - debug - - encoding - - fastestsmallesttextencoderdecoder - - 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.19(@farcaster/miniapp-sdk@0.2.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@3.25.76)': 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.1.12(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@farcaster/miniapp-wagmi-connector': 1.1.0(@farcaster/miniapp-sdk@0.2.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@tanstack/react-query': 5.90.5(react@19.2.0) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) 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.2.0 + react-dom: 19.2.0(react@19.2.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.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: 2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -6821,21 +7846,61 @@ 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.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.2.2)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(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 + eventemitter3: 5.0.1 + idb-keyval: 6.2.1 + ox: 0.6.9(typescript@5.9.3)(zod@3.25.76) + preact: 10.24.2 + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.3(@types/react@19.2.2)(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.2.2)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@4.1.12)': + 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.3)(zod@4.1.12) + preact: 10.24.2 + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + zustand: 5.0.3(@types/react@19.2.2)(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.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@3.25.76)': 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) + ox: 0.6.9(typescript@5.9.3)(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)) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.3(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)) transitivePeerDependencies: - '@types/react' - bufferutil @@ -6846,9 +7911,9 @@ snapshots: - utf-8-validate - zod - '@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.11)(utf-8-validate@5.0.10)': dependencies: - esbuild: 0.25.9 + esbuild: 0.25.11 jsdom: 26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) lodash: 4.17.21 transitivePeerDependencies: @@ -6881,13 +7946,13 @@ snapshots: dependencies: '@noble/ciphers': 1.3.0 - '@emnapi/core@1.5.0': + '@emnapi/core@1.6.0': dependencies: '@emnapi/wasi-threads': 1.1.0 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.5.0': + '@emnapi/runtime@1.6.0': dependencies: tslib: 2.8.1 optional: true @@ -6900,114 +7965,116 @@ snapshots: '@es-joy/jsdoccomment@0.50.2': dependencies: '@types/estree': 1.0.8 - '@typescript-eslint/types': 8.42.0 + '@typescript-eslint/types': 8.46.2 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.11': optional: true - '@esbuild/android-arm64@0.25.9': + '@esbuild/android-arm64@0.25.11': optional: true - '@esbuild/android-arm@0.25.9': + '@esbuild/android-arm@0.25.11': optional: true - '@esbuild/android-x64@0.25.9': + '@esbuild/android-x64@0.25.11': optional: true - '@esbuild/darwin-arm64@0.25.9': + '@esbuild/darwin-arm64@0.25.11': optional: true - '@esbuild/darwin-x64@0.25.9': + '@esbuild/darwin-x64@0.25.11': optional: true - '@esbuild/freebsd-arm64@0.25.9': + '@esbuild/freebsd-arm64@0.25.11': optional: true - '@esbuild/freebsd-x64@0.25.9': + '@esbuild/freebsd-x64@0.25.11': optional: true - '@esbuild/linux-arm64@0.25.9': + '@esbuild/linux-arm64@0.25.11': optional: true - '@esbuild/linux-arm@0.25.9': + '@esbuild/linux-arm@0.25.11': optional: true - '@esbuild/linux-ia32@0.25.9': + '@esbuild/linux-ia32@0.25.11': optional: true - '@esbuild/linux-loong64@0.25.9': + '@esbuild/linux-loong64@0.25.11': optional: true - '@esbuild/linux-mips64el@0.25.9': + '@esbuild/linux-mips64el@0.25.11': optional: true - '@esbuild/linux-ppc64@0.25.9': + '@esbuild/linux-ppc64@0.25.11': optional: true - '@esbuild/linux-riscv64@0.25.9': + '@esbuild/linux-riscv64@0.25.11': optional: true - '@esbuild/linux-s390x@0.25.9': + '@esbuild/linux-s390x@0.25.11': optional: true - '@esbuild/linux-x64@0.25.9': + '@esbuild/linux-x64@0.25.11': optional: true - '@esbuild/netbsd-arm64@0.25.9': + '@esbuild/netbsd-arm64@0.25.11': optional: true - '@esbuild/netbsd-x64@0.25.9': + '@esbuild/netbsd-x64@0.25.11': optional: true - '@esbuild/openbsd-arm64@0.25.9': + '@esbuild/openbsd-arm64@0.25.11': optional: true - '@esbuild/openbsd-x64@0.25.9': + '@esbuild/openbsd-x64@0.25.11': optional: true - '@esbuild/openharmony-arm64@0.25.9': + '@esbuild/openharmony-arm64@0.25.11': optional: true - '@esbuild/sunos-x64@0.25.9': + '@esbuild/sunos-x64@0.25.11': optional: true - '@esbuild/win32-arm64@0.25.9': + '@esbuild/win32-arm64@0.25.11': optional: true - '@esbuild/win32-ia32@0.25.9': + '@esbuild/win32-ia32@0.25.11': optional: true - '@esbuild/win32-x64@0.25.9': + '@esbuild/win32-x64@0.25.11': optional: true - '@eslint-community/eslint-utils@4.8.0(eslint@9.34.0(jiti@1.21.7))': + '@eslint-community/eslint-utils@4.9.0(eslint@9.38.0(jiti@1.21.7))': dependencies: - eslint: 9.34.0(jiti@1.21.7) + eslint: 9.38.0(jiti@1.21.7) eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.12.1': {} + '@eslint-community/regexpp@4.12.2': {} - '@eslint/config-array@0.21.0': + '@eslint/config-array@0.21.1': dependencies: - '@eslint/object-schema': 2.1.6 - debug: 4.4.1 + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 minimatch: 3.1.2 transitivePeerDependencies: - supports-color - '@eslint/config-helpers@0.3.1': {} + '@eslint/config-helpers@0.4.1': + dependencies: + '@eslint/core': 0.16.0 - '@eslint/core@0.15.2': + '@eslint/core@0.16.0': dependencies: '@types/json-schema': 7.0.15 '@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 @@ -7018,13 +8085,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.34.0': {} + '@eslint/js@9.38.0': {} - '@eslint/object-schema@2.1.6': {} + '@eslint/object-schema@2.1.7': {} - '@eslint/plugin-kit@0.3.5': + '@eslint/plugin-kit@0.4.0': dependencies: - '@eslint/core': 0.15.2 + '@eslint/core': 0.16.0 levn: 0.4.1 '@ethereumjs/common@3.2.0': @@ -7047,13 +8114,13 @@ 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)': + '@farcaster/frame-sdk@0.1.12(bufferutil@4.0.9)(typescript@5.9.3)(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) + '@farcaster/miniapp-sdk': 0.2.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@farcaster/quick-auth': 0.0.8(typescript@5.9.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.9.3)(zod@3.25.76) transitivePeerDependencies: - bufferutil - encoding @@ -7061,10 +8128,10 @@ snapshots: - 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/miniapp-core@0.4.1(bufferutil@4.0.9)(typescript@5.9.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) + '@solana/web3.js': 1.98.4(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) + ox: 0.4.4(typescript@5.9.3)(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - bufferutil @@ -7072,13 +8139,13 @@ snapshots: - 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/miniapp-sdk@0.2.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': 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/miniapp-core': 0.4.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@farcaster/quick-auth': 0.0.6(typescript@5.9.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.9.3)(zod@3.25.76) transitivePeerDependencies: - bufferutil - encoding @@ -7086,23 +8153,43 @@ 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/miniapp-wagmi-connector@1.1.0(@farcaster/miniapp-sdk@0.2.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))': + dependencies: + '@farcaster/miniapp-sdk': 0.2.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + + '@farcaster/miniapp-wagmi-connector@1.1.0(@farcaster/miniapp-sdk@0.2.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))': + dependencies: + '@farcaster/miniapp-sdk': 0.2.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + + '@farcaster/quick-auth@0.0.6(typescript@5.9.3)': 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) + jose: 5.10.0 + typescript: 5.9.3 + zod: 3.25.76 - '@farcaster/quick-auth@0.0.6(typescript@5.9.2)': + '@farcaster/quick-auth@0.0.8(typescript@5.9.3)': dependencies: jose: 5.10.0 - typescript: 5.9.2 + typescript: 5.9.3 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))': + '@gemini-wallet/core@0.2.0(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))': + dependencies: + '@metamask/rpc-errors': 7.0.2 + eventemitter3: 5.0.1 + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - supports-color + + '@gemini-wallet/core@0.2.0(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12))': 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) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) transitivePeerDependencies: - supports-color @@ -7114,9 +8201,9 @@ snapshots: dependencies: react: 19.1.1 - '@hono/node-server@1.19.1(hono@4.9.6)': + '@hono/node-server@1.19.5(hono@4.10.2)': dependencies: - hono: 4.9.6 + hono: 4.10.2 '@humanfs/core@0.19.1': {} @@ -7129,97 +8216,100 @@ snapshots: '@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.5.0 + '@emnapi/runtime': 1.6.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/cliui@8.0.2': 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 @@ -7227,13 +8317,18 @@ 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 @@ -7312,7 +8407,7 @@ snapshots: '@metamask/rpc-errors@7.0.2': dependencies: - '@metamask/utils': 11.7.0 + '@metamask/utils': 11.8.1 fast-safe-stringify: 2.1.1 transitivePeerDependencies: - supports-color @@ -7321,13 +8416,18 @@ snapshots: '@metamask/safe-event-emitter@3.1.2': {} - '@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-analytics@0.0.5': + dependencies: + openapi-fetch: 0.13.8 + + '@metamask/sdk-communication-layer@0.33.1(cross-fetch@4.1.0)(eciesjs@0.4.16)(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 date-fns: 2.30.0 - debug: 4.4.1 - eciesjs: 0.4.15 + debug: 4.3.4 + eciesjs: 0.4.16 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) @@ -7336,22 +8436,23 @@ 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)(utf-8-validate@5.0.10)': + '@metamask/sdk@0.33.1(bufferutil@4.0.9)(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)(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)(eciesjs@0.4.16)(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.1 cross-fetch: 4.1.0 - debug: 4.4.1 - eciesjs: 0.4.15 + debug: 4.3.4 + eciesjs: 0.4.16 eth-rpc-errors: 4.0.3 eventemitter2: 6.4.9 obj-multiplex: 1.0.0 @@ -7369,7 +8470,7 @@ snapshots: '@metamask/superstruct@3.2.1': {} - '@metamask/utils@11.7.0': + '@metamask/utils@11.8.1': dependencies: '@ethereumjs/tx': 4.2.0 '@metamask/superstruct': 3.2.1 @@ -7377,10 +8478,10 @@ snapshots: '@scure/base': 1.2.6 '@types/debug': 4.1.12 '@types/lodash': 4.17.20 - debug: 4.4.1 + debug: 4.4.3 lodash: 4.17.21 pony-cause: 2.1.11 - semver: 7.7.2 + semver: 7.7.3 uuid: 9.0.1 transitivePeerDependencies: - supports-color @@ -7389,8 +8490,8 @@ snapshots: dependencies: '@ethereumjs/tx': 4.2.0 '@types/debug': 4.1.12 - debug: 4.4.1 - semver: 7.7.2 + debug: 4.4.3 + semver: 7.7.3 superstruct: 1.0.4 transitivePeerDependencies: - supports-color @@ -7402,9 +8503,9 @@ 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 + semver: 7.7.3 uuid: 9.0.1 transitivePeerDependencies: - supports-color @@ -7416,132 +8517,567 @@ 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 + semver: 7.7.3 uuid: 9.0.1 transitivePeerDependencies: - supports-color '@napi-rs/wasm-runtime@0.2.12': dependencies: - '@emnapi/core': 1.5.0 - '@emnapi/runtime': 1.5.0 - '@tybys/wasm-util': 0.10.0 + '@emnapi/core': 1.6.0 + '@emnapi/runtime': 1.6.0 + '@tybys/wasm-util': 0.10.1 optional: true - '@next/env@15.5.2': {} + '@next/env@15.5.0': {} - '@next/eslint-plugin-next@15.1.7': + '@next/env@15.5.6': {} + + '@next/eslint-plugin-next@15.5.0': dependencies: fast-glob: 3.3.1 - '@next/swc-darwin-arm64@15.5.2': + '@next/swc-darwin-arm64@15.5.0': + optional: true + + '@next/swc-darwin-arm64@15.5.6': + optional: true + + '@next/swc-darwin-x64@15.5.0': + optional: true + + '@next/swc-darwin-x64@15.5.6': + optional: true + + '@next/swc-linux-arm64-gnu@15.5.0': + optional: true + + '@next/swc-linux-arm64-gnu@15.5.6': + optional: true + + '@next/swc-linux-arm64-musl@15.5.0': + optional: true + + '@next/swc-linux-arm64-musl@15.5.6': + optional: true + + '@next/swc-linux-x64-gnu@15.5.0': optional: true - '@next/swc-darwin-x64@15.5.2': + '@next/swc-linux-x64-gnu@15.5.6': optional: true - '@next/swc-linux-arm64-gnu@15.5.2': + '@next/swc-linux-x64-musl@15.5.0': optional: true - '@next/swc-linux-arm64-musl@15.5.2': + '@next/swc-linux-x64-musl@15.5.6': optional: true - '@next/swc-linux-x64-gnu@15.5.2': + '@next/swc-win32-arm64-msvc@15.5.0': optional: true - '@next/swc-linux-x64-musl@15.5.2': + '@next/swc-win32-arm64-msvc@15.5.6': optional: true - '@next/swc-win32-arm64-msvc@15.5.2': + '@next/swc-win32-x64-msvc@15.5.0': optional: true - '@next/swc-win32-x64-msvc@15.5.2': + '@next/swc-win32-x64-msvc@15.5.6': optional: true '@noble/ciphers@1.2.1': {} '@noble/ciphers@1.3.0': {} - '@noble/curves@1.4.2': + '@noble/curves@1.4.2': + dependencies: + '@noble/hashes': 1.4.0 + + '@noble/curves@1.8.0': + dependencies: + '@noble/hashes': 1.7.0 + + '@noble/curves@1.8.1': + dependencies: + '@noble/hashes': 1.7.1 + + '@noble/curves@1.9.1': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/curves@1.9.7': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/hashes@1.4.0': {} + + '@noble/hashes@1.7.0': {} + + '@noble/hashes@1.7.1': {} + + '@noble/hashes@1.8.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@nolyfill/is-core-module@1.0.39': {} + + '@paulmillr/qr@0.2.1': {} + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@pkgr/core@0.2.9': {} + + '@reown/appkit-common@1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + big.js: 6.2.2 + dayjs: 1.11.13 + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.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.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + big.js: 6.2.2 + dayjs: 1.11.13 + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(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.3)(utf-8-validate@5.0.10)(zod@4.1.12)': + dependencies: + big.js: 6.2.2 + dayjs: 1.11.13 + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@reown/appkit-controllers@1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@walletconnect/universal-provider': 2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 1.13.2(@types/react@19.2.2)(react@19.1.1) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(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-controllers@1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@walletconnect/universal-provider': 2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + valtio: 1.13.2(@types/react@19.2.2)(react@19.1.1) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + 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.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@walletconnect/universal-provider': 2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 1.13.2(@types/react@19.2.2)(react@19.2.0) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(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-pay@1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@noble/hashes': 1.4.0 + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-ui': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.1.1))(zod@3.25.76) + lit: 3.3.0 + valtio: 1.13.2(@types/react@19.2.2)(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 - '@noble/curves@1.8.0': + '@reown/appkit-pay@1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)': dependencies: - '@noble/hashes': 1.7.0 + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + '@reown/appkit-ui': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + '@reown/appkit-utils': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.1.1))(zod@4.1.12) + lit: 3.3.0 + valtio: 1.13.2(@types/react@19.2.2)(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 - '@noble/curves@1.8.1': + '@reown/appkit-pay@1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@noble/hashes': 1.7.1 + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-ui': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0))(zod@3.25.76) + lit: 3.3.0 + valtio: 1.13.2(@types/react@19.2.2)(react@19.2.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 - '@noble/curves@1.9.1': + '@reown/appkit-polyfills@1.7.8': dependencies: - '@noble/hashes': 1.8.0 + buffer: 6.0.3 - '@noble/curves@1.9.7': + '@reown/appkit-scaffold-ui@1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.1.1))(zod@3.25.76)': dependencies: - '@noble/hashes': 1.8.0 - - '@noble/hashes@1.4.0': {} - - '@noble/hashes@1.7.0': {} - - '@noble/hashes@1.7.1': {} - - '@noble/hashes@1.8.0': {} + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-ui': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.1.1))(zod@3.25.76) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(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 - '@nodelib/fs.scandir@2.1.5': + '@reown/appkit-scaffold-ui@1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.1.1))(zod@4.1.12)': dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + '@reown/appkit-ui': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + '@reown/appkit-utils': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.1.1))(zod@4.1.12) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(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 - '@nodelib/fs.walk@1.2.8': + '@reown/appkit-scaffold-ui@1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0))(zod@3.25.76)': dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.19.1 - - '@nolyfill/is-core-module@1.0.39': {} - - '@paulmillr/qr@0.2.1': {} - - '@pkgjs/parseargs@0.11.0': - optional: true - - '@pkgr/core@0.2.9': {} + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-ui': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0))(zod@3.25.76) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(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-common@1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.22.4)': + '@reown/appkit-ui@1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': 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) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(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-common@1.7.8(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.76)': + '@reown/appkit-ui@1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)': 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) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(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-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.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(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(@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.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) + lit: 3.3.0 + qrcode: 1.5.3 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -7570,14 +9106,16 @@ 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-utils@1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.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.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) - lit: 3.3.0 - valtio: 1.13.2(@types/react@19.1.12)(react@19.1.1) + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(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.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.3)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 1.13.2(@types/react@19.2.2)(react@19.1.1) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -7606,18 +9144,16 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-polyfills@1.7.8': - 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-utils@1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.1.1))(zod@4.1.12)': 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) - lit: 3.3.0 + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + '@reown/appkit-polyfills': 1.7.8 + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.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.3)(utf-8-validate@5.0.10)(zod@4.1.12) + valtio: 1.13.2(@types/react@19.2.2)(react@19.1.1) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -7644,16 +9180,18 @@ snapshots: - typescript - uploadthing - utf-8-validate - - 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-utils@1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0))(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.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) - lit: 3.3.0 - qrcode: 1.5.3 + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(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.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.3)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 1.13.2(@types/react@19.2.2)(react@19.2.0) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -7682,16 +9220,32 @@ 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-wallet@1.7.8(bufferutil@4.0.9)(typescript@5.9.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.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.9.3)(utf-8-validate@5.0.10)(zod@3.22.4) '@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(@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) + zod: 3.22.4 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + + '@reown/appkit@1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-pay': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(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.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.1.1))(zod@3.25.76) + '@reown/appkit-ui': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.1.1))(zod@3.25.76) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(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.3)(utf-8-validate@5.0.10)(zod@3.25.76) + bs58: 6.0.0 + valtio: 1.13.2(@types/react@19.2.2)(react@19.1.1) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -7720,32 +9274,64 @@ 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@1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)': 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.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + '@reown/appkit-pay': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) '@reown/appkit-polyfills': 1.7.8 - '@walletconnect/logger': 2.1.2 - zod: 3.22.4 + '@reown/appkit-scaffold-ui': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.1.1))(zod@4.1.12) + '@reown/appkit-ui': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + '@reown/appkit-utils': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.1.1))(zod@4.1.12) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(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.3)(utf-8-validate@5.0.10)(zod@4.1.12) + bs58: 6.0.0 + valtio: 1.13.2(@types/react@19.2.2)(react@19.1.1) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) 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.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.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(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.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.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-pay': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(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.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) + '@reown/appkit-scaffold-ui': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0))(zod@3.25.76) + '@reown/appkit-ui': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0))(zod@3.25.76) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(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) + '@walletconnect/universal-provider': 2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) 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.2.2)(react@19.2.0) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -7774,76 +9360,89 @@ snapshots: - utf-8-validate - zod - '@rollup/rollup-android-arm-eabi@4.50.0': + '@rollup/rollup-android-arm-eabi@4.52.5': + optional: true + + '@rollup/rollup-android-arm64@4.52.5': optional: true - '@rollup/rollup-android-arm64@4.50.0': + '@rollup/rollup-darwin-arm64@4.52.5': optional: true - '@rollup/rollup-darwin-arm64@4.50.0': + '@rollup/rollup-darwin-x64@4.52.5': optional: true - '@rollup/rollup-darwin-x64@4.50.0': + '@rollup/rollup-freebsd-arm64@4.52.5': optional: true - '@rollup/rollup-freebsd-arm64@4.50.0': + '@rollup/rollup-freebsd-x64@4.52.5': optional: true - '@rollup/rollup-freebsd-x64@4.50.0': + '@rollup/rollup-linux-arm-gnueabihf@4.52.5': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.50.0': + '@rollup/rollup-linux-arm-musleabihf@4.52.5': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.50.0': + '@rollup/rollup-linux-arm64-gnu@4.52.5': optional: true - '@rollup/rollup-linux-arm64-gnu@4.50.0': + '@rollup/rollup-linux-arm64-musl@4.52.5': optional: true - '@rollup/rollup-linux-arm64-musl@4.50.0': + '@rollup/rollup-linux-loong64-gnu@4.52.5': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.50.0': + '@rollup/rollup-linux-ppc64-gnu@4.52.5': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.50.0': + '@rollup/rollup-linux-riscv64-gnu@4.52.5': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.50.0': + '@rollup/rollup-linux-riscv64-musl@4.52.5': optional: true - '@rollup/rollup-linux-riscv64-musl@4.50.0': + '@rollup/rollup-linux-s390x-gnu@4.52.5': optional: true - '@rollup/rollup-linux-s390x-gnu@4.50.0': + '@rollup/rollup-linux-x64-gnu@4.52.5': optional: true - '@rollup/rollup-linux-x64-gnu@4.50.0': + '@rollup/rollup-linux-x64-musl@4.52.5': optional: true - '@rollup/rollup-linux-x64-musl@4.50.0': + '@rollup/rollup-openharmony-arm64@4.52.5': optional: true - '@rollup/rollup-openharmony-arm64@4.50.0': + '@rollup/rollup-win32-arm64-msvc@4.52.5': optional: true - '@rollup/rollup-win32-arm64-msvc@4.50.0': + '@rollup/rollup-win32-ia32-msvc@4.52.5': optional: true - '@rollup/rollup-win32-ia32-msvc@4.50.0': + '@rollup/rollup-win32-x64-gnu@4.52.5': optional: true - '@rollup/rollup-win32-x64-msvc@4.50.0': + '@rollup/rollup-win32-x64-msvc@4.52.5': optional: true '@rtsao/scc@1.1.0': {} - '@rushstack/eslint-patch@1.12.0': {} + '@rushstack/eslint-patch@1.14.0': {} + + '@safe-global/safe-apps-provider@0.18.6(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + events: 3.3.0 + transitivePeerDependencies: + - bufferutil + - typescript + - 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@3.25.76)': + '@safe-global/safe-apps-provider@0.18.6(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)': 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.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) events: 3.3.0 transitivePeerDependencies: - bufferutil @@ -7851,10 +9450,20 @@ 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.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@safe-global/safe-gateway-typescript-sdk': 3.23.1 + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(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.3)(utf-8-validate@5.0.10)(zod@4.1.12)': 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.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) transitivePeerDependencies: - bufferutil - typescript @@ -7881,7 +9490,7 @@ snapshots: '@scure/bip32@1.7.0': dependencies: - '@noble/curves': 1.9.1 + '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 @@ -7902,548 +9511,841 @@ 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.9.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.3)(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.9.3)(ws@8.18.3(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.9.3)(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))': + '@solana-program/system@0.8.1(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(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/sysvars': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2) + '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(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.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.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@solana/sysvars@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/sysvars': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/accounts@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.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@solana/sysvars@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/sysvars': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + + '@solana-program/token@0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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.3)(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.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': + dependencies: + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + + '@solana-program/token@0.6.0(@solana/kit@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': + dependencies: + '@solana/kit': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(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.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec': 2.3.0(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/addresses@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/accounts@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/rpc-spec': 3.0.3(typescript@5.9.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/assertions@2.3.0(typescript@5.9.2)': + '@solana/addresses@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': dependencies: - '@solana/errors': 2.3.0(typescript@5.9.2) - typescript: 5.9.2 + '@solana/assertions': 2.3.0(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/nominal-types': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder - '@solana/buffer-layout-utils@0.2.0(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@solana/addresses@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': 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) - bigint-buffer: 1.1.5 - bignumber.js: 9.3.1 + '@solana/assertions': 3.0.3(typescript@5.9.3) + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/nominal-types': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - - bufferutil - - encoding - - typescript - - utf-8-validate + - fastestsmallesttextencoderdecoder + + '@solana/assertions@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/assertions@3.0.3(typescript@5.9.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 '@solana/buffer-layout@4.0.1': dependencies: buffer: 6.0.3 - '@solana/codecs-core@2.0.0-rc.1(typescript@5.9.2)': + '@solana/codecs-core@2.3.0(typescript@5.9.3)': dependencies: - '@solana/errors': 2.0.0-rc.1(typescript@5.9.2) - typescript: 5.9.2 + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 - '@solana/codecs-core@2.3.0(typescript@5.9.2)': + '@solana/codecs-core@3.0.3(typescript@5.9.3)': dependencies: - '@solana/errors': 2.3.0(typescript@5.9.2) - typescript: 5.9.2 + '@solana/errors': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 - '@solana/codecs-data-structures@2.0.0-rc.1(typescript@5.9.2)': + '@solana/codecs-data-structures@2.3.0(typescript@5.9.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.9.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 - '@solana/codecs-data-structures@2.3.0(typescript@5.9.2)': + '@solana/codecs-data-structures@3.0.3(typescript@5.9.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': 3.0.3(typescript@5.9.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 - '@solana/codecs-numbers@2.0.0-rc.1(typescript@5.9.2)': + '@solana/codecs-numbers@2.3.0(typescript@5.9.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.3.0(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 - '@solana/codecs-numbers@2.3.0(typescript@5.9.2)': + '@solana/codecs-numbers@3.0.3(typescript@5.9.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': 3.0.3(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 - '@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/codecs-strings@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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.3.0(typescript@5.9.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) fastestsmallesttextencoderdecoder: 1.0.22 - typescript: 5.9.2 + typescript: 5.9.3 - '@solana/codecs-strings@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/codecs-strings@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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': 3.0.3(typescript@5.9.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) fastestsmallesttextencoderdecoder: 1.0.22 - typescript: 5.9.2 + typescript: 5.9.3 - '@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/codecs@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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.3.0(typescript@5.9.3) + '@solana/codecs-data-structures': 2.3.0(typescript@5.9.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/options': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/codecs@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/codecs@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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': 3.0.3(typescript@5.9.3) + '@solana/codecs-data-structures': 3.0.3(typescript@5.9.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.9.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/options': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/errors@2.0.0-rc.1(typescript@5.9.2)': + '@solana/errors@2.3.0(typescript@5.9.3)': dependencies: - chalk: 5.6.0 - commander: 12.1.0 - typescript: 5.9.2 + chalk: 5.6.2 + commander: 14.0.1 + typescript: 5.9.3 - '@solana/errors@2.3.0(typescript@5.9.2)': + '@solana/errors@3.0.3(typescript@5.9.3)': dependencies: - chalk: 5.6.0 + chalk: 5.6.2 commander: 14.0.0 - typescript: 5.9.2 + typescript: 5.9.3 + + '@solana/fast-stable-stringify@2.3.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/fast-stable-stringify@3.0.3(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/functional@2.3.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/functional@3.0.3(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/instruction-plans@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/instructions': 3.0.3(typescript@5.9.3) + '@solana/promises': 3.0.3(typescript@5.9.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder - '@solana/fast-stable-stringify@2.3.0(typescript@5.9.2)': + '@solana/instructions@2.3.0(typescript@5.9.3)': dependencies: - typescript: 5.9.2 + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 - '@solana/functional@2.3.0(typescript@5.9.2)': + '@solana/instructions@3.0.3(typescript@5.9.3)': dependencies: - typescript: 5.9.2 + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 - '@solana/instructions@2.3.0(typescript@5.9.2)': + '@solana/keys@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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/assertions': 2.3.0(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/nominal-types': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder - '@solana/keys@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/keys@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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': 3.0.3(typescript@5.9.3) + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/nominal-types': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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.9.3) + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/instructions': 2.3.0(typescript@5.9.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/programs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-parsed-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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.9.3) + '@solana/signers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/sysvars': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-confirmation': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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.9.3) + '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder + - ws - '@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.9.3)(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.3) + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/instructions': 2.3.0(typescript@5.9.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/programs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-parsed-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(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.3) + '@solana/signers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/sysvars': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-confirmation': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(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.3) + '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.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@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/accounts': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/functional': 3.0.3(typescript@5.9.3) + '@solana/instruction-plans': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/instructions': 3.0.3(typescript@5.9.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/programs': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-parsed-types': 3.0.3(typescript@5.9.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) + '@solana/rpc-subscriptions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/signers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/sysvars': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-confirmation': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - ws - '@solana/nominal-types@2.3.0(typescript@5.9.2)': + '@solana/nominal-types@2.3.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/nominal-types@3.0.3(typescript@5.9.3)': dependencies: - typescript: 5.9.2 + typescript: 5.9.3 - '@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/options@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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.3.0(typescript@5.9.3) + '@solana/codecs-data-structures': 2.3.0(typescript@5.9.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/options@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/options@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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': 3.0.3(typescript@5.9.3) + '@solana/codecs-data-structures': 3.0.3(typescript@5.9.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.9.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + typescript: 5.9.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.9.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.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/promises@2.3.0(typescript@5.9.2)': + '@solana/programs@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': dependencies: - typescript: 5.9.2 + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/promises@2.3.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 - '@solana/rpc-api@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/promises@3.0.3(typescript@5.9.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/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 + typescript: 5.9.3 + + '@solana/rpc-api@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-parsed-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec': 2.3.0(typescript@5.9.3) + '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-api@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-parsed-types': 3.0.3(typescript@5.9.3) + '@solana/rpc-spec': 3.0.3(typescript@5.9.3) + '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/rpc-parsed-types@2.3.0(typescript@5.9.2)': + '@solana/rpc-parsed-types@2.3.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/rpc-parsed-types@3.0.3(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/rpc-spec-types@2.3.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/rpc-spec-types@3.0.3(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/rpc-spec@2.3.0(typescript@5.9.3)': dependencies: - typescript: 5.9.2 + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 - '@solana/rpc-spec-types@2.3.0(typescript@5.9.2)': + '@solana/rpc-spec@3.0.3(typescript@5.9.3)': dependencies: - typescript: 5.9.2 + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 - '@solana/rpc-spec@2.3.0(typescript@5.9.2)': + '@solana/rpc-subscriptions-api@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.9.3) + '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder - '@solana/rpc-subscriptions-api@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/rpc-subscriptions-api@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-subscriptions-spec': 3.0.3(typescript@5.9.3) + '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.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.9.3)(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/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.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.9.3) + '@solana/subscribable': 2.3.0(typescript@5.9.3) + typescript: 5.9.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))': + '@solana/rpc-subscriptions-channel-websocket@2.3.0(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.9.3) + '@solana/subscribable': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + + '@solana/rpc-subscriptions-channel-websocket@3.0.3(typescript@5.9.3)(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 + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/functional': 3.0.3(typescript@5.9.3) + '@solana/rpc-subscriptions-spec': 3.0.3(typescript@5.9.3) + '@solana/subscribable': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 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-spec@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/promises': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + '@solana/subscribable': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/rpc-subscriptions-spec@3.0.3(typescript@5.9.3)': + dependencies: + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/promises': 3.0.3(typescript@5.9.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) + '@solana/subscribable': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/rpc-subscriptions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/fast-stable-stringify': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/promises': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-subscriptions-api': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-subscriptions-channel-websocket': 2.3.0(typescript@5.9.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.9.3) + '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/subscribable': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + + '@solana/rpc-subscriptions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/fast-stable-stringify': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/promises': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-subscriptions-api': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-subscriptions-channel-websocket': 2.3.0(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.9.3) + '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/subscribable': 2.3.0(typescript@5.9.3) + typescript: 5.9.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@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/fast-stable-stringify': 3.0.3(typescript@5.9.3) + '@solana/functional': 3.0.3(typescript@5.9.3) + '@solana/promises': 3.0.3(typescript@5.9.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) + '@solana/rpc-subscriptions-api': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-subscriptions-channel-websocket': 3.0.3(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-subscriptions-spec': 3.0.3(typescript@5.9.3) + '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/subscribable': 3.0.3(typescript@5.9.3) + typescript: 5.9.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.9.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/nominal-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-transformers@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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': 3.0.3(typescript@5.9.3) + '@solana/functional': 3.0.3(typescript@5.9.3) + '@solana/nominal-types': 3.0.3(typescript@5.9.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/rpc-transport-http@2.3.0(typescript@5.9.2)': + '@solana/rpc-transport-http@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + undici-types: 7.16.0 + + '@solana/rpc-transport-http@3.0.3(typescript@5.9.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': 3.0.3(typescript@5.9.3) + '@solana/rpc-spec': 3.0.3(typescript@5.9.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) + typescript: 5.9.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.9.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.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/nominal-types': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/rpc@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/rpc-types@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': 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/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.9.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/nominal-types': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/signers@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/rpc@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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/errors': 2.3.0(typescript@5.9.3) + '@solana/fast-stable-stringify': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/rpc-api': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-spec': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-transport-http': 2.3.0(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.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/rpc@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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/errors': 3.0.3(typescript@5.9.3) + '@solana/fast-stable-stringify': 3.0.3(typescript@5.9.3) + '@solana/functional': 3.0.3(typescript@5.9.3) + '@solana/rpc-api': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-spec': 3.0.3(typescript@5.9.3) + '@solana/rpc-spec-types': 3.0.3(typescript@5.9.3) + '@solana/rpc-transformers': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-transport-http': 3.0.3(typescript@5.9.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 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/signers@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/instructions': 2.3.0(typescript@5.9.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/nominal-types': 2.3.0(typescript@5.9.3) + '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 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/signers@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': 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) - buffer: 6.0.3 + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/instructions': 3.0.3(typescript@5.9.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/nominal-types': 3.0.3(typescript@5.9.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - - bufferutil - - encoding - fastestsmallesttextencoderdecoder - - typescript - - utf-8-validate - '@solana/subscribable@2.3.0(typescript@5.9.2)': + '@solana/subscribable@2.3.0(typescript@5.9.3)': dependencies: - '@solana/errors': 2.3.0(typescript@5.9.2) - typescript: 5.9.2 + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 - '@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/subscribable@3.0.3(typescript@5.9.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/errors': 3.0.3(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/accounts': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/sysvars@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/accounts': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/transaction-confirmation@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/promises': 2.3.0(typescript@5.9.3) + '@solana/rpc': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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.9.3) + '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder + - ws - '@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-confirmation@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(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.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/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/promises': 2.3.0(typescript@5.9.3) + '@solana/rpc': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(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.3) + '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.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))': + '@solana/transaction-confirmation@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(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/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/promises': 3.0.3(typescript@5.9.3) + '@solana/rpc': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-subscriptions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - ws - '@solana/transaction-messages@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.2)': + '@solana/transaction-messages@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-data-structures': 2.3.0(typescript@5.9.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/instructions': 2.3.0(typescript@5.9.3) + '@solana/nominal-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/transaction-messages@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.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-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/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/codecs-data-structures': 3.0.3(typescript@5.9.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/functional': 3.0.3(typescript@5.9.3) + '@solana/instructions': 3.0.3(typescript@5.9.3) + '@solana/nominal-types': 3.0.3(typescript@5.9.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/transactions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-data-structures': 2.3.0(typescript@5.9.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/instructions': 2.3.0(typescript@5.9.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/nominal-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@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/transactions@3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 3.0.3(typescript@5.9.3) + '@solana/codecs-data-structures': 3.0.3(typescript@5.9.3) + '@solana/codecs-numbers': 3.0.3(typescript@5.9.3) + '@solana/codecs-strings': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 3.0.3(typescript@5.9.3) + '@solana/functional': 3.0.3(typescript@5.9.3) + '@solana/instructions': 3.0.3(typescript@5.9.3) + '@solana/keys': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/nominal-types': 3.0.3(typescript@5.9.3) + '@solana/rpc-types': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-messages': 3.0.3(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/web3.js@1.98.4(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@solana/wallet-standard-features@1.3.0': + dependencies: + '@wallet-standard/base': 1.1.0 + '@wallet-standard/features': 1.1.0 + + '@solana/web3.js@1.98.4(bufferutil@4.0.9)(typescript@5.9.3)(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 - '@solana/codecs-numbers': 2.3.0(typescript@5.9.2) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) agentkeepalive: 4.6.0 bn.js: 5.2.2 borsh: 0.7.0 @@ -8452,7 +10354,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.2.0 superstruct: 2.0.2 transitivePeerDependencies: - bufferutil @@ -8460,56 +10362,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.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)': + '@svgr/core@8.1.0(typescript@5.9.3)': 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) + cosmiconfig: 8.3.6(typescript@5.9.3) snake-case: 3.0.4 transitivePeerDependencies: - supports-color @@ -8517,38 +10419,38 @@ 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))': + '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.9.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.28.4 + '@svgr/babel-preset': 8.1.0(@babel/core@7.28.4) + '@svgr/core': 8.1.0(typescript@5.9.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.9.3))(typescript@5.9.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.9.3) + cosmiconfig: 8.3.6(typescript@5.9.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.9.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.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.3) + '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3)) + '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3))(typescript@5.9.3) transitivePeerDependencies: - supports-color - typescript @@ -8561,16 +10463,21 @@ snapshots: dependencies: tslib: 2.8.1 - '@tanstack/query-core@5.85.9': {} + '@tanstack/query-core@5.90.5': {} - '@tanstack/react-query@5.85.9(react@19.1.1)': + '@tanstack/react-query@5.90.5(react@19.1.1)': dependencies: - '@tanstack/query-core': 5.85.9 + '@tanstack/query-core': 5.90.5 react: 19.1.1 + '@tanstack/react-query@5.90.5(react@19.2.0)': + dependencies: + '@tanstack/query-core': 5.90.5 + react: 19.2.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 @@ -8578,15 +10485,16 @@ snapshots: '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 22.18.0 + '@types/node': 22.18.12 - '@types/chai@5.2.2': + '@types/chai@5.2.3': dependencies: '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 '@types/connect@3.4.38': dependencies: - '@types/node': 22.18.0 + '@types/node': 22.18.12 '@types/debug@4.1.12': dependencies: @@ -8596,18 +10504,18 @@ snapshots: '@types/estree@1.0.8': {} - '@types/express-serve-static-core@5.0.7': + '@types/express-serve-static-core@5.1.0': dependencies: - '@types/node': 22.18.0 + '@types/node': 22.18.12 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 - '@types/send': 0.17.5 + '@types/send': 1.2.0 '@types/express@5.0.3': dependencies: '@types/body-parser': 1.19.6 - '@types/express-serve-static-core': 5.0.7 - '@types/serve-static': 1.15.8 + '@types/express-serve-static-core': 5.1.0 + '@types/serve-static': 1.15.9 '@types/http-errors@2.0.5': {} @@ -8623,11 +10531,11 @@ snapshots: '@types/node@12.20.55': {} - '@types/node@20.19.12': + '@types/node@20.19.23': dependencies: undici-types: 6.21.0 - '@types/node@22.18.0': + '@types/node@22.18.12': dependencies: undici-types: 6.21.0 @@ -8635,23 +10543,27 @@ snapshots: '@types/range-parser@1.2.7': {} - '@types/react-dom@19.1.9(@types/react@19.1.12)': + '@types/react-dom@19.2.2(@types/react@19.2.2)': dependencies: - '@types/react': 19.1.12 + '@types/react': 19.2.2 - '@types/react@19.1.12': + '@types/react@19.2.2': dependencies: csstype: 3.1.3 '@types/send@0.17.5': dependencies: '@types/mime': 1.3.5 - '@types/node': 22.18.0 + '@types/node': 22.18.12 - '@types/serve-static@1.15.8': + '@types/send@1.2.0': + dependencies: + '@types/node': 22.18.12 + + '@types/serve-static@1.15.9': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 22.18.0 + '@types/node': 22.18.12 '@types/send': 0.17.5 '@types/trusted-types@2.0.7': {} @@ -8660,103 +10572,103 @@ snapshots: '@types/ws@7.4.7': dependencies: - '@types/node': 22.18.0 + '@types/node': 22.18.12 '@types/ws@8.18.1': dependencies: - '@types/node': 22.18.0 + '@types/node': 22.18.12 - '@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.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.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) + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.46.2 + '@typescript-eslint/type-utils': 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.46.2 + eslint: 9.38.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.9.3) + typescript: 5.9.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.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 - debug: 4.4.1 - eslint: 9.34.0(jiti@1.21.7) - typescript: 5.9.2 + '@typescript-eslint/scope-manager': 8.46.2 + '@typescript-eslint/types': 8.46.2 + '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.46.2 + debug: 4.4.3 + eslint: 9.38.0(jiti@1.21.7) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.42.0(typescript@5.9.2)': + '@typescript-eslint/project-service@8.46.2(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.42.0(typescript@5.9.2) - '@typescript-eslint/types': 8.42.0 - debug: 4.4.1 - typescript: 5.9.2 + '@typescript-eslint/tsconfig-utils': 8.46.2(typescript@5.9.3) + '@typescript-eslint/types': 8.46.2 + debug: 4.4.3 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.42.0': + '@typescript-eslint/scope-manager@8.46.2': dependencies: - '@typescript-eslint/types': 8.42.0 - '@typescript-eslint/visitor-keys': 8.42.0 + '@typescript-eslint/types': 8.46.2 + '@typescript-eslint/visitor-keys': 8.46.2 - '@typescript-eslint/tsconfig-utils@8.42.0(typescript@5.9.2)': + '@typescript-eslint/tsconfig-utils@8.46.2(typescript@5.9.3)': dependencies: - typescript: 5.9.2 + typescript: 5.9.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.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) - 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 + '@typescript-eslint/types': 8.46.2 + '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.38.0(jiti@1.21.7) + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.42.0': {} + '@typescript-eslint/types@8.46.2': {} - '@typescript-eslint/typescript-estree@8.42.0(typescript@5.9.2)': + '@typescript-eslint/typescript-estree@8.46.2(typescript@5.9.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 - debug: 4.4.1 + '@typescript-eslint/project-service': 8.46.2(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.46.2(typescript@5.9.3) + '@typescript-eslint/types': 8.46.2 + '@typescript-eslint/visitor-keys': 8.46.2 + debug: 4.4.3 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 + semver: 7.7.3 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.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.9.0(eslint@9.38.0(jiti@1.21.7)) + '@typescript-eslint/scope-manager': 8.46.2 + '@typescript-eslint/types': 8.46.2 + '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.9.3) + eslint: 9.38.0(jiti@1.21.7) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.42.0': + '@typescript-eslint/visitor-keys@8.46.2': dependencies: - '@typescript-eslint/types': 8.42.0 + '@typescript-eslint/types': 8.46.2 eslint-visitor-keys: 4.2.1 '@unrs/resolver-binding-android-arm-eabi@1.11.1': @@ -8829,19 +10741,19 @@ snapshots: '@vitest/expect@3.2.4': dependencies: - '@types/chai': 5.2.2 + '@types/chai': 5.2.3 '@vitest/spy': 3.2.4 '@vitest/utils': 3.2.4 chai: 5.3.3 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.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 - magic-string: 0.30.18 + magic-string: 0.30.19 optionalDependencies: - vite: 6.3.5(@types/node@22.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + vite: 6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6) '@vitest/pretty-format@3.2.4': dependencies: @@ -8851,38 +10763,227 @@ snapshots: dependencies: '@vitest/utils': 3.2.4 pathe: 2.0.3 - strip-literal: 3.0.0 + strip-literal: 3.1.0 '@vitest/snapshot@3.2.4': dependencies: '@vitest/pretty-format': 3.2.4 - magic-string: 0.30.18 + magic-string: 0.30.19 pathe: 2.0.3 - '@vitest/spy@3.2.4': + '@vitest/spy@3.2.4': + dependencies: + tinyspy: 4.0.4 + + '@vitest/utils@3.2.4': + dependencies: + '@vitest/pretty-format': 3.2.4 + loupe: 3.2.1 + tinyrainbow: 2.0.0 + + '@wagmi/connectors@5.11.2(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(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.2.2)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(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.2.2)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(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.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@metamask/sdk': 0.33.1(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.3)(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.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(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.5(react@19.1.1))(@types/react@19.2.2)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + optionalDependencies: + typescript: 5.9.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' + - '@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.2(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@vercel/functions@2.2.13)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(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.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@3.25.76) + '@coinbase/wallet-sdk': 4.3.6(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@3.25.76) + '@gemini-wallet/core': 0.2.0(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@metamask/sdk': 0.33.1(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.3)(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.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(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.5(react@19.2.0))(@types/react@19.2.2)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + optionalDependencies: + typescript: 5.9.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' + - '@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@6.1.0(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76)': dependencies: - tinyspy: 4.0.3 + '@base-org/account': 1.1.1(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(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.2.2)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(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.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@metamask/sdk': 0.33.1(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.3)(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.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(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.5(react@19.1.1))(@types/react@19.2.2)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + optionalDependencies: + typescript: 5.9.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' + - '@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 - '@vitest/utils@3.2.4': + '@wagmi/connectors@6.1.0(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12))(zod@4.1.12))(zod@4.1.12)': dependencies: - '@vitest/pretty-format': 3.2.4 - loupe: 3.2.1 - tinyrainbow: 2.0.0 + '@base-org/account': 1.1.1(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@4.1.12) + '@coinbase/wallet-sdk': 4.3.6(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(zod@4.1.12) + '@gemini-wallet/core': 0.2.0(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)) + '@metamask/sdk': 0.33.1(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.3)(utf-8-validate@5.0.10)(zod@4.1.12) + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + cbw-sdk: '@coinbase/wallet-sdk@3.9.3' + porto: 0.2.19(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)))(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12))(zod@4.1.12)) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + optionalDependencies: + typescript: 5.9.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' + - '@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.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@6.1.0(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@vercel/functions@2.2.13)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(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.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)) - '@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) + '@base-org/account': 1.1.1(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@3.25.76) + '@coinbase/wallet-sdk': 4.3.6(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@3.25.76) + '@gemini-wallet/core': 0.2.0(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@metamask/sdk': 0.33.1(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.3)(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.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) 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) + porto: 0.2.19(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -8895,6 +10996,7 @@ snapshots: - '@netlify/blobs' - '@planetscale/database' - '@react-native-async-storage/async-storage' + - '@tanstack/react-query' - '@types/react' - '@upstash/redis' - '@vercel/blob' @@ -8911,24 +11013,109 @@ snapshots: - uploadthing - use-sync-external-store - utf-8-validate + - wagmi - 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.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))': + dependencies: + eventemitter3: 5.0.1 + mipd: 0.0.7(typescript@5.9.3) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.0(@types/react@19.2.2)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) + optionalDependencies: + '@tanstack/query-core': 5.90.5 + typescript: 5.9.3 + transitivePeerDependencies: + - '@types/react' + - immer + - react + - use-sync-external-store + + '@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12))': + dependencies: + eventemitter3: 5.0.1 + mipd: 0.0.7(typescript@5.9.3) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + zustand: 5.0.0(@types/react@19.2.2)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) + optionalDependencies: + '@tanstack/query-core': 5.90.5 + typescript: 5.9.3 + transitivePeerDependencies: + - '@types/react' + - immer + - react + - use-sync-external-store + + '@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(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.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.9.3) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.0(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)) optionalDependencies: - '@tanstack/query-core': 5.85.9 - typescript: 5.9.2 + '@tanstack/query-core': 5.90.5 + typescript: 5.9.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)': + '@wallet-standard/app@1.1.0': + dependencies: + '@wallet-standard/base': 1.1.0 + + '@wallet-standard/base@1.1.0': {} + + '@wallet-standard/features@1.1.0': + dependencies: + '@wallet-standard/base': 1.1.0 + + '@walletconnect/core@2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(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(@vercel/functions@2.2.13) + '@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.3)(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(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)': dependencies: '@walletconnect/heartbeat': 1.2.2 '@walletconnect/jsonrpc-provider': 1.0.14 @@ -8942,11 +11129,141 @@ snapshots: '@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/utils': 2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + '@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(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(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(@vercel/functions@2.2.13) + '@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.3)(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(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)': + 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/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.3)(utf-8-validate@5.0.10)(zod@4.1.12) '@walletconnect/window-getters': 1.0.1 es-toolkit: 1.33.0 events: 3.3.0 - uint8arrays: 3.1.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/environment@1.0.1': + dependencies: + tslib: 1.14.1 + + '@walletconnect/ethereum-provider@2.21.1(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@reown/appkit': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@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.3)(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.3)(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.3)(utf-8-validate@5.0.10)(zod@3.25.76) + events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -8959,6 +11276,7 @@ snapshots: - '@netlify/blobs' - '@planetscale/database' - '@react-native-async-storage/async-storage' + - '@types/react' - '@upstash/redis' - '@vercel/blob' - '@vercel/functions' @@ -8966,31 +11284,27 @@ snapshots: - aws4fetch - bufferutil - db0 + - encoding - ioredis + - react - typescript - uploadthing - 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/ethereum-provider@2.21.1(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)': dependencies: - '@walletconnect/heartbeat': 1.2.2 + '@reown/appkit': 1.7.8(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + '@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/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/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/sign-client': 2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) '@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/window-getters': 1.0.1 - es-toolkit: 1.33.0 + '@walletconnect/universal-provider': 2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + '@walletconnect/utils': 2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) events: 3.3.0 - uint8arrays: 3.1.0 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -9003,6 +11317,7 @@ snapshots: - '@netlify/blobs' - '@planetscale/database' - '@react-native-async-storage/async-storage' + - '@types/react' - '@upstash/redis' - '@vercel/blob' - '@vercel/functions' @@ -9010,28 +11325,26 @@ snapshots: - aws4fetch - bufferutil - db0 + - encoding - ioredis + - react - typescript - uploadthing - utf-8-validate - zod - '@walletconnect/environment@1.0.1': - 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.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': 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.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) '@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/sign-client': 2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(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/universal-provider': 2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(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.3)(utf-8-validate@5.0.10)(zod@3.25.76) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -9112,7 +11425,7 @@ snapshots: 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.17.1(@vercel/functions@2.2.13)(idb-keyval@6.2.2) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -9154,16 +11467,88 @@ 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(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@walletconnect/core': 2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(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(@vercel/functions@2.2.13) + '@walletconnect/utils': 2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(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(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)': 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(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) '@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/utils': 2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + 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(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@walletconnect/core': 2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(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(@vercel/functions@2.2.13) + '@walletconnect/utils': 2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -9190,16 +11575,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(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)': 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(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) '@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/utils': 2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -9288,7 +11673,47 @@ snapshots: - 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(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + 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/logger': 2.1.2 + '@walletconnect/sign-client': 2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(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.3)(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.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)': dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/jsonrpc-http-connection': 1.0.8 @@ -9297,9 +11722,9 @@ snapshots: '@walletconnect/jsonrpc-utils': 1.0.8 '@walletconnect/keyvaluestorage': 1.1.1(@vercel/functions@2.2.13) '@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/sign-client': 2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) '@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/utils': 2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) es-toolkit: 1.33.0 events: 3.3.0 transitivePeerDependencies: @@ -9328,7 +11753,7 @@ 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(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/jsonrpc-http-connection': 1.0.8 @@ -9337,9 +11762,9 @@ snapshots: '@walletconnect/jsonrpc-utils': 1.0.8 '@walletconnect/keyvaluestorage': 1.1.1(@vercel/functions@2.2.13) '@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/sign-client': 2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(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/utils': 2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) es-toolkit: 1.33.0 events: 3.3.0 transitivePeerDependencies: @@ -9368,7 +11793,91 @@ 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/universal-provider@2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)': + 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/logger': 2.1.2 + '@walletconnect/sign-client': 2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + '@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.3)(utf-8-validate@5.0.10)(zod@4.1.12) + 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(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(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(@vercel/functions@2.2.13) + '@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/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.3)(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' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/utils@2.21.0(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)': dependencies: '@noble/ciphers': 1.2.1 '@noble/curves': 1.8.1 @@ -9386,7 +11895,51 @@ snapshots: 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.3)(utf-8-validate@5.0.10)(zod@4.1.12) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/utils@2.21.1(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(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(@vercel/functions@2.2.13) + '@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/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.3)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -9412,7 +11965,7 @@ 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(@vercel/functions@2.2.13)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)': dependencies: '@noble/ciphers': 1.2.1 '@noble/curves': 1.8.1 @@ -9430,7 +11983,7 @@ snapshots: 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.3)(utf-8-validate@5.0.10)(zod@4.1.12) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -9465,26 +12018,51 @@ snapshots: '@walletconnect/window-getters': 1.0.1 tslib: 1.14.1 - abitype@1.0.6(typescript@5.9.2)(zod@3.25.76): + abitype@1.0.6(typescript@5.9.3)(zod@3.25.76): + optionalDependencies: + typescript: 5.9.3 + zod: 3.25.76 + + abitype@1.0.8(typescript@5.9.3)(zod@3.25.76): + optionalDependencies: + typescript: 5.9.3 + zod: 3.25.76 + + abitype@1.0.8(typescript@5.9.3)(zod@4.1.12): + optionalDependencies: + typescript: 5.9.3 + zod: 4.1.12 + + abitype@1.1.0(typescript@5.9.3)(zod@3.22.4): optionalDependencies: - typescript: 5.9.2 - zod: 3.25.76 + typescript: 5.9.3 + zod: 3.22.4 - abitype@1.0.8(typescript@5.9.2)(zod@3.25.76): + abitype@1.1.0(typescript@5.9.3)(zod@3.25.76): optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 zod: 3.25.76 - abitype@1.1.0(typescript@5.9.2)(zod@3.22.4): + abitype@1.1.0(typescript@5.9.3)(zod@4.1.12): + optionalDependencies: + typescript: 5.9.3 + zod: 4.1.12 + + abitype@1.1.1(typescript@5.9.3)(zod@3.22.4): optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 zod: 3.22.4 - abitype@1.1.0(typescript@5.9.2)(zod@3.25.76): + abitype@1.1.1(typescript@5.9.3)(zod@3.25.76): optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 zod: 3.25.76 + abitype@1.1.1(typescript@5.9.3)(zod@4.1.12): + optionalDependencies: + typescript: 5.9.3 + zod: 4.1.12 + accepts@1.3.8: dependencies: mime-types: 2.1.35 @@ -9511,13 +12089,13 @@ snapshots: ansi-regex@5.0.1: {} - ansi-regex@6.2.0: {} + ansi-regex@6.2.2: {} ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 - ansi-styles@6.2.1: {} + ansi-styles@6.2.3: {} any-promise@1.3.0: {} @@ -9621,14 +12199,14 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 - axe-core@4.10.3: {} + axe-core@4.11.0: {} - 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 @@ -9638,27 +12216,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) - core-js-compat: 3.45.1 + '@babel/core': 7.28.4 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.4) + core-js-compat: 3.46.0 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 @@ -9672,20 +12250,12 @@ snapshots: base64-js@1.5.1: {} - big.js@6.2.2: {} - - bigint-buffer@1.1.5: - dependencies: - bindings: 1.5.0 + baseline-browser-mapping@2.8.19: {} - bignumber.js@9.3.1: {} + big.js@6.2.2: {} binary-extensions@2.3.0: {} - bindings@1.5.0: - dependencies: - file-uri-to-path: 1.0.0 - bn.js@5.2.2: {} body-parser@1.20.3: @@ -9728,12 +12298,13 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.25.4: + browserslist@4.27.0: dependencies: - caniuse-lite: 1.0.30001739 - electron-to-chromium: 1.5.214 - node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.25.4) + baseline-browser-mapping: 2.8.19 + caniuse-lite: 1.0.30001751 + electron-to-chromium: 1.5.239 + node-releases: 2.0.26 + update-browserslist-db: 1.1.4(browserslist@4.27.0) bs58@4.0.1: dependencies: @@ -9752,9 +12323,9 @@ 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.11): dependencies: - esbuild: 0.25.9 + esbuild: 0.25.11 load-tsconfig: 0.2.5 bytes@3.1.2: {} @@ -9786,7 +12357,7 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001739: {} + caniuse-lite@1.0.30001751: {} chai@5.3.3: dependencies: @@ -9801,7 +12372,7 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 - chalk@5.6.0: {} + chalk@5.6.2: {} charenc@0.0.2: {} @@ -9841,28 +12412,16 @@ snapshots: color-name@1.1.4: {} - color-string@1.9.1: - dependencies: - color-name: 1.1.4 - simple-swizzle: 0.2.2 - optional: true - - color@4.2.3: - dependencies: - color-convert: 2.0.1 - color-string: 1.9.1 - optional: true - combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 comlink@4.4.2: {} - commander@12.1.0: {} - commander@14.0.0: {} + commander@14.0.1: {} + commander@2.20.3: {} commander@4.1.1: {} @@ -9891,20 +12450,20 @@ snapshots: cookie@0.7.1: {} - core-js-compat@3.45.1: + core-js-compat@3.46.0: dependencies: - browserslist: 4.25.4 + browserslist: 4.27.0 core-util-is@1.0.3: {} - cosmiconfig@8.3.6(typescript@5.9.2): + cosmiconfig@8.3.6(typescript@5.9.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.9.3 crc-32@1.2.2: {} @@ -9992,7 +12551,7 @@ snapshots: date-fns@2.30.0: dependencies: - '@babel/runtime': 7.28.3 + '@babel/runtime': 7.28.4 dayjs@1.11.13: {} @@ -10004,11 +12563,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 @@ -10044,9 +12603,13 @@ 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.2.2)(react@19.1.1)): dependencies: - valtio: 1.13.2(@types/react@19.1.12)(react@19.1.1) + valtio: 1.13.2(@types/react@19.2.2)(react@19.1.1) + + derive-valtio@0.1.0(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0)): + dependencies: + valtio: 1.13.2(@types/react@19.2.2)(react@19.2.0) destr@2.0.5: {} @@ -10054,7 +12617,7 @@ snapshots: detect-browser@5.3.0: {} - detect-libc@2.0.4: + detect-libc@2.1.2: optional: true didyoumean@1.2.2: {} @@ -10105,7 +12668,7 @@ snapshots: eastasianwidth@0.2.0: {} - eciesjs@0.4.15: + eciesjs@0.4.16: dependencies: '@ecies/ciphers': 0.2.4(@noble/ciphers@1.3.0) '@noble/ciphers': 1.3.0 @@ -10114,7 +12677,7 @@ snapshots: ee-first@1.1.1: {} - electron-to-chromium@1.5.214: {} + electron-to-chromium@1.5.239: {} emoji-regex@8.0.0: {} @@ -10133,7 +12696,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 @@ -10148,7 +12711,7 @@ snapshots: entities@6.0.1: {} - error-ex@1.3.2: + error-ex@1.3.4: dependencies: is-arrayish: 0.2.1 @@ -10263,34 +12826,34 @@ snapshots: dependencies: es6-promise: 4.2.8 - esbuild@0.25.9: + esbuild@0.25.11: 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.11 + '@esbuild/android-arm': 0.25.11 + '@esbuild/android-arm64': 0.25.11 + '@esbuild/android-x64': 0.25.11 + '@esbuild/darwin-arm64': 0.25.11 + '@esbuild/darwin-x64': 0.25.11 + '@esbuild/freebsd-arm64': 0.25.11 + '@esbuild/freebsd-x64': 0.25.11 + '@esbuild/linux-arm': 0.25.11 + '@esbuild/linux-arm64': 0.25.11 + '@esbuild/linux-ia32': 0.25.11 + '@esbuild/linux-loong64': 0.25.11 + '@esbuild/linux-mips64el': 0.25.11 + '@esbuild/linux-ppc64': 0.25.11 + '@esbuild/linux-riscv64': 0.25.11 + '@esbuild/linux-s390x': 0.25.11 + '@esbuild/linux-x64': 0.25.11 + '@esbuild/netbsd-arm64': 0.25.11 + '@esbuild/netbsd-x64': 0.25.11 + '@esbuild/openbsd-arm64': 0.25.11 + '@esbuild/openbsd-x64': 0.25.11 + '@esbuild/openharmony-arm64': 0.25.11 + '@esbuild/sunos-x64': 0.25.11 + '@esbuild/win32-arm64': 0.25.11 + '@esbuild/win32-ia32': 0.25.11 + '@esbuild/win32-x64': 0.25.11 escalade@3.2.0: {} @@ -10298,21 +12861,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.5.0(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.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) + '@next/eslint-plugin-next': 15.5.0 + '@rushstack/eslint-patch': 1.14.0 + '@typescript-eslint/eslint-plugin': 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': 8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + eslint: 9.38.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.38.0(jiti@1.21.7)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-react: 7.37.5(eslint@9.38.0(jiti@1.21.7)) + eslint-plugin-react-hooks: 5.2.0(eslint@9.38.0(jiti@1.21.7)) optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 transitivePeerDependencies: - eslint-import-resolver-webpack - eslint-plugin-import-x @@ -10322,37 +12885,37 @@ snapshots: dependencies: debug: 3.2.7 is-core-module: 2.16.1 - resolve: 1.22.10 + resolve: 1.22.11 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.38.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) - get-tsconfig: 4.10.1 + debug: 4.4.3 + eslint: 9.38.0(jiti@1.21.7) + get-tsconfig: 4.13.0 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.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3) + eslint: 9.38.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.38.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -10361,9 +12924,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.38.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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.38.0(jiti@1.21.7)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -10375,39 +12938,39 @@ 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.46.2(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.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.38.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.34.0(jiti@1.21.7) + eslint: 9.38.0(jiti@1.21.7) espree: 10.4.0 esquery: 1.6.0 parse-imports-exports: 0.2.4 - semver: 7.7.2 + semver: 7.7.3 spdx-expression-parse: 4.0.0 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.38.0(jiti@1.21.7)): dependencies: aria-query: 5.3.2 array-includes: 3.1.9 array.prototype.flatmap: 1.3.3 ast-types-flow: 0.0.8 - axe-core: 4.10.3 + axe-core: 4.11.0 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.38.0(jiti@1.21.7) hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -10416,18 +12979,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.4(eslint@9.38.0(jiti@1.21.7))(prettier@3.5.2): dependencies: - eslint: 9.34.0(jiti@1.21.7) + eslint: 9.38.0(jiti@1.21.7) prettier: 3.5.2 prettier-linter-helpers: 1.0.0 synckit: 0.11.11 - eslint-plugin-react-hooks@5.2.0(eslint@9.34.0(jiti@1.21.7)): + eslint-plugin-react-hooks@5.2.0(eslint@9.38.0(jiti@1.21.7)): dependencies: - eslint: 9.34.0(jiti@1.21.7) + eslint: 9.38.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.38.0(jiti@1.21.7)): dependencies: array-includes: 3.1.9 array.prototype.findlast: 1.2.5 @@ -10435,7 +12998,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.38.0(jiti@1.21.7) estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -10458,25 +13021,24 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.34.0(jiti@1.21.7): + eslint@9.38.0(jiti@1.21.7): dependencies: - '@eslint-community/eslint-utils': 4.8.0(eslint@9.34.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-community/eslint-utils': 4.9.0(eslint@9.38.0(jiti@1.21.7)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.1 + '@eslint/config-helpers': 0.4.1 + '@eslint/core': 0.16.0 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.34.0 - '@eslint/plugin-kit': 0.3.5 + '@eslint/js': 9.38.0 + '@eslint/plugin-kit': 0.4.0 '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 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 @@ -10653,8 +13215,6 @@ snapshots: dependencies: flat-cache: 4.0.1 - file-uri-to-path@1.0.0: {} - fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -10685,9 +13245,9 @@ snapshots: fix-dts-default-cjs-exports@1.0.1: dependencies: - magic-string: 0.30.18 + magic-string: 0.30.19 mlly: 1.8.0 - rollup: 4.50.0 + rollup: 4.52.5 flat-cache@4.0.1: dependencies: @@ -10735,6 +13295,8 @@ snapshots: functions-have-names@1.2.3: {} + generator-function@2.0.1: {} + gensync@1.0.0-beta.2: {} get-caller-file@2.0.5: {} @@ -10763,7 +13325,7 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 - get-tsconfig@4.10.1: + get-tsconfig@4.13.0: dependencies: resolve-pkg-maps: 1.0.0 @@ -10814,7 +13376,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 @@ -10841,7 +13403,7 @@ snapshots: dependencies: function-bind: 1.1.2 - hono@4.9.6: {} + hono@4.10.2: {} html-encoding-sniffer@4.0.0: dependencies: @@ -10858,14 +13420,14 @@ snapshots: http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.4 - 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 @@ -10923,9 +13485,6 @@ snapshots: is-arrayish@0.2.1: {} - is-arrayish@0.3.2: - optional: true - is-async-function@2.1.1: dependencies: async-function: 1.0.0 @@ -10951,7 +13510,7 @@ snapshots: is-bun-module@2.0.0: dependencies: - semver: 7.7.2 + semver: 7.7.3 is-callable@1.2.7: {} @@ -10978,9 +13537,10 @@ snapshots: is-fullwidth-code-point@3.0.0: {} - is-generator-function@1.1.0: + is-generator-function@1.1.2: dependencies: call-bound: 1.0.4 + generator-function: 2.0.1 get-proto: 1.0.1 has-tostringtag: 1.0.2 safe-regex-test: 1.1.0 @@ -11123,7 +13683,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 @@ -11141,8 +13701,6 @@ snapshots: - supports-color - utf-8-validate - jsesc@3.0.2: {} - jsesc@3.1.0: {} json-buffer@3.0.1: {} @@ -11252,7 +13810,7 @@ snapshots: dependencies: yallist: 3.1.1 - magic-string@0.30.18: + magic-string@0.30.19: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -11303,9 +13861,9 @@ snapshots: minipass@7.1.2: {} - mipd@0.0.7(typescript@5.9.2): + mipd@0.0.7(typescript@5.9.3): optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 mlly@1.8.0: dependencies: @@ -11316,6 +13874,8 @@ snapshots: ms@2.0.0: {} + ms@2.1.2: {} + ms@2.1.3: {} multiformats@9.9.0: {} @@ -11328,31 +13888,77 @@ snapshots: nanoid@3.3.11: {} - napi-postinstall@0.3.3: {} + napi-postinstall@0.3.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.5.0(@babel/core@7.28.4)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: - '@next/env': 15.5.2 + '@next/env': 15.5.0 '@swc/helpers': 0.5.15 - caniuse-lite: 1.0.30001739 + caniuse-lite: 1.0.30001751 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.4 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + + next@15.5.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + dependencies: + '@next/env': 15.5.0 + '@swc/helpers': 0.5.15 + caniuse-lite: 1.0.30001751 + postcss: 8.4.31 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + styled-jsx: 5.1.6(react@19.2.0) + 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.4 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + + next@15.5.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + dependencies: + '@next/env': 15.5.6 + '@swc/helpers': 0.5.15 + caniuse-lite: 1.0.30001751 + postcss: 8.4.31 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + styled-jsx: 5.1.6(react@19.2.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.5.6 + '@next/swc-darwin-x64': 15.5.6 + '@next/swc-linux-arm64-gnu': 15.5.6 + '@next/swc-linux-arm64-musl': 15.5.6 + '@next/swc-linux-x64-gnu': 15.5.6 + '@next/swc-linux-x64-musl': 15.5.6 + '@next/swc-win32-arm64-msvc': 15.5.6 + '@next/swc-win32-x64-msvc': 15.5.6 + sharp: 0.34.4 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -11372,9 +13978,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.26: {} normalize-path@3.0.0: {} @@ -11382,7 +13988,7 @@ snapshots: dependencies: boolbase: 1.0.0 - nwsapi@2.2.21: {} + nwsapi@2.2.22: {} obj-multiplex@1.0.0: dependencies: @@ -11450,6 +14056,12 @@ snapshots: dependencies: wrappy: 1.0.2 + openapi-fetch@0.13.8: + dependencies: + openapi-typescript-helpers: 0.0.15 + + openapi-typescript-helpers@0.0.15: {} + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -11465,75 +14077,133 @@ 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.9.3)(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.0(typescript@5.9.2)(zod@3.25.76) + abitype: 1.1.1(typescript@5.9.3)(zod@3.25.76) eventemitter3: 5.0.1 optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 transitivePeerDependencies: - zod - ox@0.6.7(typescript@5.9.2)(zod@3.25.76): + ox@0.6.7(typescript@5.9.3)(zod@3.25.76): 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) + '@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.3)(zod@3.25.76) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + + ox@0.6.7(typescript@5.9.3)(zod@4.1.12): + 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.3)(zod@4.1.12) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + + ox@0.6.9(typescript@5.9.3)(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.3)(zod@3.25.76) eventemitter3: 5.0.1 optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 transitivePeerDependencies: - zod - ox@0.6.9(typescript@5.9.2)(zod@3.25.76): + ox@0.6.9(typescript@5.9.3)(zod@4.1.12): 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.0(typescript@5.9.2)(zod@3.25.76) + abitype: 1.1.1(typescript@5.9.3)(zod@4.1.12) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + + ox@0.9.12(typescript@5.9.3)(zod@4.1.12): + 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.3)(zod@4.1.12) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + + ox@0.9.6(typescript@5.9.3)(zod@3.22.4): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.1.1(typescript@5.9.3)(zod@3.22.4) eventemitter3: 5.0.1 optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 transitivePeerDependencies: - zod - ox@0.9.3(typescript@5.9.2)(zod@3.22.4): + ox@0.9.6(typescript@5.9.3)(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.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) + abitype: 1.1.1(typescript@5.9.3)(zod@3.25.76) eventemitter3: 5.0.1 optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 transitivePeerDependencies: - zod - ox@0.9.3(typescript@5.9.2)(zod@3.25.76): + ox@0.9.6(typescript@5.9.3)(zod@4.1.12): dependencies: - '@adraffy/ens-normalize': 1.11.0 + '@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@3.25.76) + abitype: 1.1.1(typescript@5.9.3)(zod@4.1.12) eventemitter3: 5.0.1 optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 transitivePeerDependencies: - zod @@ -11568,7 +14238,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 @@ -11644,6 +14314,66 @@ snapshots: pony-cause@2.1.11: {} + porto@0.2.19(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)): + dependencies: + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + hono: 4.10.2 + idb-keyval: 6.2.2 + mipd: 0.0.7(typescript@5.9.3) + ox: 0.9.12(typescript@5.9.3)(zod@4.1.12) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zod: 4.1.12 + zustand: 5.0.8(@types/react@19.2.2)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) + optionalDependencies: + '@tanstack/react-query': 5.90.5(react@19.1.1) + react: 19.1.1 + typescript: 5.9.3 + wagmi: 2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(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.5(react@19.1.1))(@types/react@19.2.2)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)))(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12))(zod@4.1.12)): + dependencies: + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)) + hono: 4.10.2 + idb-keyval: 6.2.2 + mipd: 0.0.7(typescript@5.9.3) + ox: 0.9.12(typescript@5.9.3)(zod@4.1.12) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + zod: 4.1.12 + zustand: 5.0.8(@types/react@19.2.2)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)) + optionalDependencies: + '@tanstack/react-query': 5.90.5(react@19.1.1) + react: 19.1.1 + typescript: 5.9.3 + wagmi: 2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12))(zod@4.1.12) + transitivePeerDependencies: + - '@types/react' + - immer + - use-sync-external-store + + porto@0.2.19(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)): + dependencies: + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + hono: 4.10.2 + idb-keyval: 6.2.2 + mipd: 0.0.7(typescript@5.9.3) + ox: 0.9.12(typescript@5.9.3)(zod@4.1.12) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zod: 4.1.12 + zustand: 5.0.8(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)) + optionalDependencies: + '@tanstack/react-query': 5.90.5(react@19.2.0) + react: 19.2.0 + typescript: 5.9.3 + wagmi: 2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(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): @@ -11651,28 +14381,20 @@ snapshots: postcss: 8.5.6 postcss-value-parser: 4.2.0 read-cache: 1.0.0 - resolve: 1.22.10 + resolve: 1.22.11 - 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 - postcss-load-config@4.0.2(postcss@8.5.6): - dependencies: - lilconfig: 3.1.3 - yaml: 2.8.1 - 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.6): 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.6 postcss-nested@6.2.0(postcss@8.5.6): dependencies: @@ -11700,7 +14422,7 @@ snapshots: preact@10.24.2: {} - preact@10.27.1: {} + preact@10.27.2: {} prelude-ls@1.2.1: {} @@ -11780,10 +14502,17 @@ snapshots: react: 19.1.1 scheduler: 0.26.0 + react-dom@19.2.0(react@19.2.0): + dependencies: + react: 19.2.0 + scheduler: 0.27.0 + react-is@16.13.1: {} react@19.1.1: {} + react@19.2.0: {} + read-cache@1.0.0: dependencies: pify: 2.3.0 @@ -11823,7 +14552,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 @@ -11838,20 +14567,20 @@ 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 require-directory@2.1.1: {} @@ -11863,7 +14592,7 @@ snapshots: resolve-pkg-maps@1.0.0: {} - resolve@1.22.10: + resolve@1.22.11: dependencies: is-core-module: 2.16.1 path-parse: 1.0.7 @@ -11877,34 +14606,35 @@ snapshots: reusify@1.1.0: {} - rollup@4.50.0: + rollup@4.52.5: 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.52.5 + '@rollup/rollup-android-arm64': 4.52.5 + '@rollup/rollup-darwin-arm64': 4.52.5 + '@rollup/rollup-darwin-x64': 4.52.5 + '@rollup/rollup-freebsd-arm64': 4.52.5 + '@rollup/rollup-freebsd-x64': 4.52.5 + '@rollup/rollup-linux-arm-gnueabihf': 4.52.5 + '@rollup/rollup-linux-arm-musleabihf': 4.52.5 + '@rollup/rollup-linux-arm64-gnu': 4.52.5 + '@rollup/rollup-linux-arm64-musl': 4.52.5 + '@rollup/rollup-linux-loong64-gnu': 4.52.5 + '@rollup/rollup-linux-ppc64-gnu': 4.52.5 + '@rollup/rollup-linux-riscv64-gnu': 4.52.5 + '@rollup/rollup-linux-riscv64-musl': 4.52.5 + '@rollup/rollup-linux-s390x-gnu': 4.52.5 + '@rollup/rollup-linux-x64-gnu': 4.52.5 + '@rollup/rollup-linux-x64-musl': 4.52.5 + '@rollup/rollup-openharmony-arm64': 4.52.5 + '@rollup/rollup-win32-arm64-msvc': 4.52.5 + '@rollup/rollup-win32-ia32-msvc': 4.52.5 + '@rollup/rollup-win32-x64-gnu': 4.52.5 + '@rollup/rollup-win32-x64-msvc': 4.52.5 fsevents: 2.3.3 - rpc-websockets@9.1.3: + rpc-websockets@9.2.0: dependencies: '@swc/helpers': 0.5.17 '@types/uuid': 8.3.4 @@ -11956,9 +14686,11 @@ snapshots: scheduler@0.26.0: {} + scheduler@0.27.0: {} + semver@6.3.1: {} - semver@7.7.2: {} + semver@7.7.3: {} send@0.19.0: dependencies: @@ -12017,36 +14749,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 - semver: 7.7.2 + '@img/colour': 1.0.0 + detect-libc: 2.1.2 + semver: 7.7.3 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: @@ -12087,11 +14819,6 @@ snapshots: signal-exit@4.1.0: {} - simple-swizzle@0.2.2: - dependencies: - is-arrayish: 0.3.2 - optional: true - snake-case@3.0.4: dependencies: dot-case: 3.0.4 @@ -12100,7 +14827,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: @@ -12111,7 +14838,7 @@ 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 @@ -12144,7 +14871,7 @@ snapshots: statuses@2.0.1: {} - std-env@3.9.0: {} + std-env@3.10.0: {} stop-iteration-iterator@1.1.0: dependencies: @@ -12171,7 +14898,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: @@ -12235,24 +14962,29 @@ 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: {} strip-json-comments@3.1.1: {} - strip-literal@3.0.0: + strip-literal@3.1.0: 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 + + styled-jsx@5.1.6(react@19.2.0): + dependencies: + client-only: 0.0.1 + react: 19.2.0 sucrase@3.35.0: dependencies: @@ -12294,7 +15026,7 @@ snapshots: tailwind-merge@2.6.0: {} - tailwindcss@3.4.17: + tailwindcss@3.4.18(tsx@4.20.6): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -12312,14 +15044,15 @@ 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-load-config: 4.0.2(postcss@8.5.6) + postcss-js: 4.1.0(postcss@8.5.6) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.20.6) postcss-nested: 6.2.0(postcss@8.5.6) postcss-selector-parser: 6.1.2 - resolve: 1.22.10 + resolve: 1.22.11 sucrase: 3.35.0 transitivePeerDependencies: - - ts-node + - tsx + - yaml text-encoding-utf-8@1.0.2: {} @@ -12339,7 +15072,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 @@ -12348,7 +15081,7 @@ snapshots: tinyrainbow@2.0.0: {} - tinyspy@4.0.3: {} + tinyspy@4.0.4: {} tldts-core@6.1.86: {} @@ -12356,7 +15089,7 @@ snapshots: dependencies: tldts-core: 6.1.86 - to-buffer@1.2.1: + to-buffer@1.2.2: dependencies: isarray: 2.0.5 safe-buffer: 5.2.1 @@ -12384,15 +15117,15 @@ snapshots: tree-kill@1.2.2: {} - ts-api-utils@2.1.0(typescript@5.9.2): + ts-api-utils@2.1.0(typescript@5.9.3): dependencies: - typescript: 5.9.2 + typescript: 5.9.3 ts-interface-checker@0.1.13: {} - tsconfck@3.1.6(typescript@5.9.2): + tsconfck@3.1.6(typescript@5.9.3): optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 tsconfig-paths@3.15.0: dependencies: @@ -12405,67 +15138,67 @@ 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.6)(typescript@5.9.3): dependencies: - bundle-require: 5.1.0(esbuild@0.25.9) + bundle-require: 5.1.0(esbuild@0.25.11) 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.11 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.6) resolve-from: 5.0.0 - rollup: 4.50.0 + rollup: 4.52.5 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 - typescript: 5.9.2 + typescript: 5.9.3 transitivePeerDependencies: - jiti - supports-color - tsx - yaml - tsx@4.20.5: + tsx@4.20.6: dependencies: - esbuild: 0.25.9 - get-tsconfig: 4.10.1 + esbuild: 0.25.11 + get-tsconfig: 4.13.0 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 type-check@0.4.0: dependencies: @@ -12509,7 +15242,7 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript@5.9.2: {} + typescript@5.9.3: {} ufo@1.6.1: {} @@ -12528,24 +15261,24 @@ snapshots: undici-types@6.21.0: {} - undici-types@7.15.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: {} unpipe@1.0.0: {} unrs-resolver@1.11.1: dependencies: - napi-postinstall: 0.3.3 + napi-postinstall: 0.3.4 optionalDependencies: '@unrs/resolver-binding-android-arm-eabi': 1.11.1 '@unrs/resolver-binding-android-arm64': 1.11.1 @@ -12567,7 +15300,7 @@ snapshots: '@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): + unstorage@1.17.1(@vercel/functions@2.2.13)(idb-keyval@6.2.2): dependencies: anymatch: 3.1.3 chokidar: 4.0.3 @@ -12581,9 +15314,9 @@ snapshots: '@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.4(browserslist@4.27.0): dependencies: - browserslist: 4.25.4 + browserslist: 4.27.0 escalade: 3.2.0 picocolors: 1.1.1 @@ -12595,10 +15328,18 @@ snapshots: dependencies: react: 19.1.1 + use-sync-external-store@1.2.0(react@19.2.0): + dependencies: + react: 19.2.0 + use-sync-external-store@1.4.0(react@19.1.1): dependencies: react: 19.1.1 + use-sync-external-store@1.4.0(react@19.2.0): + dependencies: + react: 19.2.0 + utf-8-validate@5.0.10: dependencies: node-gyp-build: 4.8.4 @@ -12609,7 +15350,7 @@ snapshots: dependencies: inherits: 2.0.4 is-arguments: 1.2.0 - is-generator-function: 1.1.0 + is-generator-function: 1.1.2 is-typed-array: 1.1.15 which-typed-array: 1.1.19 @@ -12619,75 +15360,118 @@ 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.2.2)(react@19.1.1): 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.2.2)(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.12 + '@types/react': 19.2.2 react: 19.1.1 + valtio@1.13.2(@types/react@19.2.2)(react@19.2.0): + dependencies: + derive-valtio: 0.1.0(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0)) + proxy-compare: 2.6.0 + use-sync-external-store: 1.2.0(react@19.2.0) + optionalDependencies: + '@types/react': 19.2.2 + react: 19.2.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.9.3)(utf-8-validate@5.0.10)(zod@3.25.76): + 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.3)(zod@3.25.76) + 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.3)(zod@3.25.76) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.23.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12): 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.9.3)(zod@4.1.12) 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.9.3)(zod@4.1.12) ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(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.3)(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.3)(zod@3.22.4) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.9.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.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76): 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) + abitype: 1.1.0(typescript@5.9.3)(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.22.4) + ox: 0.9.6(typescript@5.9.3)(zod@3.25.76) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.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.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12): 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.25.76) + abitype: 1.1.0(typescript@5.9.3)(zod@4.1.12) 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) + ox: 0.9.6(typescript@5.9.3)(zod@4.1.12) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.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.18.12)(jiti@1.21.7)(tsx@4.20.6): 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.18.0)(jiti@1.21.7)(tsx@4.20.5)(yaml@2.8.1) + vite: 6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6) transitivePeerDependencies: - '@types/node' - jiti @@ -12702,60 +15486,59 @@ 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.9.3)(vite@6.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6)): dependencies: - debug: 4.4.1 + debug: 4.4.3 globrex: 0.1.2 - tsconfck: 3.1.6(typescript@5.9.2) + tsconfck: 3.1.6(typescript@5.9.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.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6) 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.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6): dependencies: - esbuild: 0.25.9 + esbuild: 0.25.11 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.50.0 - tinyglobby: 0.2.14 + rollup: 4.52.5 + tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 22.18.0 + '@types/node': 22.18.12 fsevents: 2.3.3 jiti: 1.21.7 - tsx: 4.20.5 - yaml: 2.8.1 + tsx: 4.20.6 - 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.18.12)(jiti@1.21.7)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(tsx@4.20.6): dependencies: - '@types/chai': 5.2.2 + '@types/chai': 5.2.3 '@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.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6)) '@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.1 + debug: 4.4.3 expect-type: 1.2.2 - magic-string: 0.30.18 + magic-string: 0.30.19 pathe: 2.0.3 picomatch: 4.0.3 - std-env: 3.9.0 + std-env: 3.10.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.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.4.1(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6) + vite-node: 3.2.4(@types/node@22.18.12)(jiti@1.21.7)(tsx@4.20.6) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 - '@types/node': 22.18.0 + '@types/node': 22.18.12 jsdom: 26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - jiti @@ -12775,16 +15558,94 @@ 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.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76): + dependencies: + '@tanstack/react-query': 5.90.5(react@19.1.1) + '@wagmi/connectors': 6.1.0(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(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.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + optionalDependencies: + typescript: 5.9.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' + - '@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.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12))(zod@4.1.12): 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)) + '@tanstack/react-query': 5.90.5(react@19.1.1) + '@wagmi/connectors': 6.1.0(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)))(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.1.1))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.1.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12))(zod@4.1.12))(zod@4.1.12) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.1))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12)) 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) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.1.12) + optionalDependencies: + typescript: 5.9.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' + - '@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.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76): + dependencies: + '@tanstack/react-query': 5.90.5(react@19.2.0) + '@wagmi/connectors': 6.1.0(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@vercel/functions@2.2.13)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.18.2(@tanstack/query-core@5.90.5)(@tanstack/react-query@5.90.5(react@19.2.0))(@types/react@19.2.2)(@vercel/functions@2.2.13)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.5)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + react: 19.2.0 + use-sync-external-store: 1.4.0(react@19.2.0) + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -12860,7 +15721,7 @@ snapshots: is-async-function: 2.1.1 is-date-object: 1.1.0 is-finalizationregistry: 1.1.1 - is-generator-function: 1.1.0 + is-generator-function: 1.1.2 is-regex: 1.2.1 is-weakref: 1.1.1 isarray: 2.0.5 @@ -12912,9 +15773,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: {} @@ -12938,13 +15799,13 @@ snapshots: 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.9.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.19.5(hono@4.10.2) + axios: 1.12.2 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) + hono: 4.10.2 + viem: 2.38.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - bufferutil @@ -12965,8 +15826,6 @@ snapshots: yallist@3.1.1: {} - yaml@2.8.1: {} - yargs-parser@18.1.3: dependencies: camelcase: 5.3.1 @@ -12992,14 +15851,40 @@ snapshots: 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)): + zod@4.1.12: {} + + zustand@5.0.0(@types/react@19.2.2)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)): + optionalDependencies: + '@types/react': 19.2.2 + react: 19.1.1 + use-sync-external-store: 1.4.0(react@19.1.1) + + zustand@5.0.0(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)): + optionalDependencies: + '@types/react': 19.2.2 + react: 19.2.0 + use-sync-external-store: 1.4.0(react@19.2.0) + + zustand@5.0.3(@types/react@19.2.2)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)): optionalDependencies: - '@types/react': 19.1.12 + '@types/react': 19.2.2 react: 19.1.1 use-sync-external-store: 1.4.0(react@19.1.1) - 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.3(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)): optionalDependencies: - '@types/react': 19.1.12 + '@types/react': 19.2.2 + react: 19.2.0 + use-sync-external-store: 1.4.0(react@19.2.0) + + zustand@5.0.8(@types/react@19.2.2)(react@19.1.1)(use-sync-external-store@1.4.0(react@19.1.1)): + optionalDependencies: + '@types/react': 19.2.2 react: 19.1.1 use-sync-external-store: 1.4.0(react@19.1.1) + + zustand@5.0.8(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)): + optionalDependencies: + '@types/react': 19.2.2 + react: 19.2.0 + use-sync-external-store: 1.4.0(react@19.2.0) diff --git a/typescript/pnpm-workspace.yaml b/typescript/pnpm-workspace.yaml index 6aff8b61f..e40e53d72 100644 --- a/typescript/pnpm-workspace.yaml +++ b/typescript/pnpm-workspace.yaml @@ -1,5 +1,9 @@ packages: - - packages/* + - packages/core + - packages/extensions/* + - packages/http/* + - packages/mechanisms/* + - packages/legacy/* - examples/facilitator - examples/**/* - site diff --git a/typescript/site/app/api/x402/session-token/route.ts b/typescript/site/app/api/x402/session-token/route.ts index 3d9293fc2..6deb0a95f 100644 --- a/typescript/site/app/api/x402/session-token/route.ts +++ b/typescript/site/app/api/x402/session-token/route.ts @@ -1 +1,22 @@ -export { POST } from "x402-next"; +import type { NextRequest } from "next/server"; +import { POST as handleSessionToken } from "x402-next"; + +export const runtime = "nodejs"; + +/** + * Route handler that delegates to the default x402 session-token endpoint. + * + * @param request - Incoming Next.js request. + * @param context - Route params context (unused). + * @param context.params - Route params promise (unused). + * @returns Session token response. + */ +export async function POST( + request: NextRequest, + context: { params: Promise> }, +) { + void context; + type SessionTokenHandler = (req: NextRequest) => ReturnType; + const delegate = handleSessionToken as unknown as SessionTokenHandler; + return delegate(request); +} diff --git a/typescript/site/app/ecosystem/partners-data/onchain/metadata.json b/typescript/site/app/ecosystem/partners-data/onchain/metadata.json new file mode 100644 index 000000000..1e24dc468 --- /dev/null +++ b/typescript/site/app/ecosystem/partners-data/onchain/metadata.json @@ -0,0 +1,7 @@ +{ + "name": "Onchain", + "description": "Onchain is x402's Intelligent Intermediary Layer for Aggregating Facilitators.", + "logoUrl": "/logos/onchain.png", + "websiteUrl": "https://onchain.fi", + "category": "Services/Endpoints" +} \ No newline at end of file diff --git a/typescript/site/eslint.config.js b/typescript/site/eslint.config.js index adbf24d2f..3c3ba7e69 100644 --- a/typescript/site/eslint.config.js +++ b/typescript/site/eslint.config.js @@ -7,7 +7,7 @@ import importPlugin from "eslint-plugin-import"; export default [ { - ignores: ["dist/**", "node_modules/**", ".next/**"], + ignores: ["dist/**", "node_modules/**", ".next/**", "**/*.d.ts"], }, { files: ["**/*.ts"], diff --git a/typescript/site/eslint.config.mjs b/typescript/site/eslint.config.mjs index c85fb67c4..794b92e59 100644 --- a/typescript/site/eslint.config.mjs +++ b/typescript/site/eslint.config.mjs @@ -10,6 +10,9 @@ const compat = new FlatCompat({ }); const eslintConfig = [ + { + ignores: ["**/next-env.d.ts", "**/.next/**", "**/node_modules/**", "*.d.ts"] + }, ...compat.extends("next/core-web-vitals", "next/typescript"), ]; diff --git a/typescript/site/middleware.ts b/typescript/site/middleware.ts index 1874c5483..931f69fae 100644 --- a/typescript/site/middleware.ts +++ b/typescript/site/middleware.ts @@ -68,8 +68,10 @@ export const middleware = async (req: NextRequest) => { if (geolocationResponse) { return geolocationResponse; } - - return x402PaymentMiddleware(req); + const delegate = x402PaymentMiddleware as unknown as ( + request: NextRequest, + ) => ReturnType; + return delegate(req); }; // Configure which paths the middleware should run on diff --git a/typescript/site/package.json b/typescript/site/package.json index 0b1eb2e22..0f8665314 100644 --- a/typescript/site/package.json +++ b/typescript/site/package.json @@ -17,9 +17,9 @@ "dependencies": { "@heroicons/react": "^2.2.0", "@vercel/functions": "^2.2.8", - "next": "^15.2.4", - "react": "^19.0.0", - "react-dom": "^19.0.0", + "next": "15.5.0", + "react": "19.1.1", + "react-dom": "19.1.1", "viem": "^2.21.26", "wagmi": "^2.15.6", "x402": "workspace:*", @@ -36,7 +36,7 @@ "@typescript-eslint/eslint-plugin": "^8.29.1", "@typescript-eslint/parser": "^8.29.1", "eslint": "^9.24.0", - "eslint-config-next": "15.1.7", + "eslint-config-next": "15.5.0", "eslint-plugin-import": "^2.31.0", "eslint-plugin-jsdoc": "^50.6.9", "eslint-plugin-prettier": "^5.2.6", diff --git a/typescript/site/public/logos/onchain.png b/typescript/site/public/logos/onchain.png new file mode 100644 index 000000000..8142a777f Binary files /dev/null and b/typescript/site/public/logos/onchain.png differ