From 2f9a9ee23fa551032d7f02ae6dd7bc574cec5883 Mon Sep 17 00:00:00 2001 From: WarTech9 Date: Sun, 22 Feb 2026 18:30:45 -0500 Subject: [PATCH 1/6] add browser example. --- README.md | 77 +- examples/README.md | 38 +- examples/browser-wagmi/.env.example | 6 + examples/browser-wagmi/README.md | 93 + examples/browser-wagmi/index.html | 35 + examples/browser-wagmi/package.json | 34 + examples/browser-wagmi/src/App.tsx | 75 + .../browser-wagmi/src/components/SwapForm.tsx | 227 + .../src/components/SwapProgress.tsx | 115 + examples/browser-wagmi/src/config/wagmi.ts | 17 + .../browser-wagmi/src/hooks/useClawSwap.ts | 225 + .../src/hooks/usePhantomWallet.ts | 60 + examples/browser-wagmi/src/main.tsx | 21 + examples/browser-wagmi/src/styles.css | 407 ++ examples/browser-wagmi/src/vite-env.d.ts | 10 + examples/browser-wagmi/tsconfig.json | 11 + examples/browser-wagmi/vite.config.ts | 18 + examples/browser/package.json | 3 + examples/browser/src/App.tsx | 76 +- examples/browser/src/components/QuoteForm.tsx | 30 +- .../browser/src/components/StatusPanel.tsx | 66 +- .../browser/src/components/SwapButton.tsx | 159 +- examples/browser/src/hooks/useWallet.ts | 238 +- examples/browser/src/styles.css | 25 +- examples/browser/src/vite-env.d.ts | 10 + examples/node-cli/e2e/sdk-integration.ts | 3 +- package.json | 1 + packages/sdk/src/utils/http.ts | 2 +- pnpm-lock.yaml | 4046 ++++++++++++++++- pnpm-workspace.yaml | 1 + 30 files changed, 5916 insertions(+), 213 deletions(-) create mode 100644 examples/browser-wagmi/.env.example create mode 100644 examples/browser-wagmi/README.md create mode 100644 examples/browser-wagmi/index.html create mode 100644 examples/browser-wagmi/package.json create mode 100644 examples/browser-wagmi/src/App.tsx create mode 100644 examples/browser-wagmi/src/components/SwapForm.tsx create mode 100644 examples/browser-wagmi/src/components/SwapProgress.tsx create mode 100644 examples/browser-wagmi/src/config/wagmi.ts create mode 100644 examples/browser-wagmi/src/hooks/useClawSwap.ts create mode 100644 examples/browser-wagmi/src/hooks/usePhantomWallet.ts create mode 100644 examples/browser-wagmi/src/main.tsx create mode 100644 examples/browser-wagmi/src/styles.css create mode 100644 examples/browser-wagmi/src/vite-env.d.ts create mode 100644 examples/browser-wagmi/tsconfig.json create mode 100644 examples/browser-wagmi/vite.config.ts create mode 100644 examples/browser/src/vite-env.d.ts diff --git a/README.md b/README.md index 1408c8a..94a0442 100644 --- a/README.md +++ b/README.md @@ -20,12 +20,12 @@ Learn more: [x402.org](https://x402.org) ## Prerequisites -Before using ClawSwap, you need: - -- **Node.js** >= 18.0.0 +- **Node.js** >= 18.0.0 (server-side) or **modern browser** (client-side — Chrome, Firefox, Safari, Edge) - **Package Manager**: npm, pnpm, or yarn -- **For Solana → Base swaps**: Solana wallet with private key (base58-encoded), 0.5 USDC (swap fee), ~0.01 SOL (gas) -- **For Base → Solana swaps**: EVM wallet with private key (0x-prefixed hex), USDC on Base, small amount of ETH on Base (~$0.001 gas) +- **For Solana → Base swaps**: Solana wallet with 0.5 USDC (swap fee) + ~0.01 SOL (gas) +- **For Base → Solana swaps**: EVM wallet with USDC on Base + small amount of ETH (~$0.001 gas) + +> The SDK has zero Node.js dependencies and works in any environment with the Fetch API.
Getting a Solana Wallet @@ -205,6 +205,73 @@ const result = await client.waitForSettlement(swap.orderId, { console.log(`Swap completed: ${result.destinationAmount} tokens delivered`); ``` +## Web App Integration + +The SDK works natively in the browser — no polyfills or Node.js shims needed. For a comprehensive guide, see [Web Integration Guide](./docs/web-integration.md). + +### Browser Quick Start (Base → Solana) + +```bash +npm install @clawswap/sdk viem +``` + +```typescript +import { ClawSwapClient, isEvmSource } from '@clawswap/sdk'; +import { createWalletClient, createPublicClient, custom, http } from 'viem'; +import { base } from 'viem/chains'; + +// 1. Connect browser wallet (MetaMask, Coinbase Wallet, etc.) +const [account] = await window.ethereum.request({ method: 'eth_requestAccounts' }); +const walletClient = createWalletClient({ + account, + chain: base, + transport: custom(window.ethereum), +}); + +// 2. Create SDK client (no x402 payment needed for Base source — it's free) +const client = new ClawSwapClient(); + +// 3. Execute swap +const swap = await client.executeSwap({ + sourceChainId: 'base', + sourceTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC + destinationChainId: 'solana', + destinationTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC + amount: '1000000', // 1 USDC + senderAddress: account, + recipientAddress: 'your-solana-address', +}); + +// 4. Sign and submit with browser wallet (MetaMask will pop up) +if (isEvmSource(swap)) { + const publicClient = createPublicClient({ chain: base, transport: http() }); + for (const tx of swap.transactions) { + const hash = await walletClient.sendTransaction({ + to: tx.to as `0x${string}`, + data: tx.data as `0x${string}`, + value: BigInt(tx.value), + }); + await publicClient.waitForTransactionReceipt({ hash }); + console.log(`TX confirmed: https://basescan.org/tx/${hash}`); + } +} + +// 5. Monitor settlement +const result = await client.waitForSettlement(swap.orderId, { + timeout: 300_000, + onStatusUpdate: (s) => console.log(`Status: ${s.status}`), +}); +``` + +### Integration Approaches + +| Approach | Dependencies | Best For | +|----------|-------------|----------| +| **Raw viem** | `viem` | Simple apps, custom wallet UIs | +| **wagmi + ConnectKit** | `wagmi`, `viem`, `connectkit` | Production React/Next.js apps | + +See [examples/browser/](./examples/browser/) for raw viem and [examples/browser-wagmi/](./examples/browser-wagmi/) for wagmi v2. + ## Supported Frameworks | Framework | Package | Status | diff --git a/examples/README.md b/examples/README.md index 371041b..11d8425 100644 --- a/examples/README.md +++ b/examples/README.md @@ -53,9 +53,9 @@ pnpm example:node -- status [Full Documentation →](./node-cli/README.md) -### 2. Browser Example +### 2. Browser Example (Raw viem) -Interactive web application with wallet connection. +Interactive web application with direct MetaMask/injected wallet integration. ```bash # Start dev server @@ -66,6 +66,28 @@ pnpm example:browser [Full Documentation →](./browser/README.md) +### 3. Browser Example (wagmi + ConnectKit) + +Production-ready React app with wagmi v2 wallet management. Supports MetaMask, Coinbase Wallet, WalletConnect, and more. + +```bash +# Start dev server +pnpm example:browser-wagmi + +# Open http://localhost:5174 +``` + +[Full Documentation →](./browser-wagmi/README.md) + +### Choosing a Browser Example + +| Feature | Raw viem (`browser/`) | wagmi + ConnectKit (`browser-wagmi/`) | +|---------|----------------------|--------------------------------------| +| Wallet support | MetaMask (injected) | MetaMask, Coinbase, WalletConnect, etc. | +| Chain switching | Manual | Automatic | +| Dependencies | `viem` | `wagmi`, `viem`, `connectkit` | +| Best for | Simple apps, non-React | Production React/Next.js | + ## Test Modes The examples support three test modes: @@ -117,7 +139,9 @@ examples/ │ └── validators.ts # Input validation ├── node-cli/ # Node.js CLI example │ └── ... -└── browser/ # Browser example +├── browser/ # Browser example (raw viem) +│ └── ... +└── browser-wagmi/ # Browser example (wagmi + ConnectKit) └── ... ``` @@ -151,9 +175,15 @@ CLAWSWAP_API_URL=https://... # Optional: override API URL TEST_MODE=dry-run # mock | dry-run | full ``` -### Browser (`.env`) +### Browser — Raw viem (`.env`) +```bash +VITE_CLAWSWAP_API_URL=https://... # Optional: override API URL +``` + +### Browser — wagmi (`.env`) ```bash VITE_CLAWSWAP_API_URL=https://... # Optional: override API URL +VITE_WC_PROJECT_ID=... # Optional: WalletConnect project ID ``` ## Running in CI/CD diff --git a/examples/browser-wagmi/.env.example b/examples/browser-wagmi/.env.example new file mode 100644 index 0000000..9113072 --- /dev/null +++ b/examples/browser-wagmi/.env.example @@ -0,0 +1,6 @@ +# ClawSwap API URL (optional) +VITE_CLAWSWAP_API_URL=https://api.clawswap.dev + +# WalletConnect project ID (optional, for WalletConnect wallets) +# Get one at https://cloud.walletconnect.com +VITE_WC_PROJECT_ID= diff --git a/examples/browser-wagmi/README.md b/examples/browser-wagmi/README.md new file mode 100644 index 0000000..4936402 --- /dev/null +++ b/examples/browser-wagmi/README.md @@ -0,0 +1,93 @@ +# ClawSwap SDK - wagmi v2 + ConnectKit Example + +Production-ready browser example using [wagmi v2](https://wagmi.sh) and [ConnectKit](https://docs.family.co/connectkit) for wallet management. + +## What This Demonstrates + +- **wagmi v2** for wallet connection, chain management, and transaction sending +- **ConnectKit** for a polished wallet connection UI (MetaMask, Coinbase Wallet, WalletConnect, etc.) +- **ClawSwap SDK** for cross-chain swap execution (quote, execute, sign, monitor) +- **Custom `useClawSwap` hook** showing how to bridge the SDK with wagmi + +## Prerequisites + +- MetaMask, Coinbase Wallet, or other browser wallet +- Base network with USDC (for Base-source swaps) + +## Running + +From the monorepo root: + +```bash +pnpm install +pnpm build +pnpm example:browser-wagmi +``` + +Open [http://localhost:5174](http://localhost:5174). + +## Environment Variables + +Create a `.env` file (optional): + +```bash +# Override API URL (optional) +VITE_CLAWSWAP_API_URL=https://api.clawswap.dev + +# WalletConnect project ID (optional, needed for WalletConnect wallets) +# Get one at https://cloud.walletconnect.com +VITE_WC_PROJECT_ID=your_project_id +``` + +## Key Files + +| File | Description | +|------|-------------| +| `src/config/wagmi.ts` | wagmi configuration with Base chain and connectors | +| `src/hooks/useClawSwap.ts` | Custom hook wrapping ClawSwap SDK with wagmi wallet/public clients | +| `src/components/SwapForm.tsx` | Combined quote + execute form component | +| `src/components/SwapProgress.tsx` | Cross-chain settlement status polling | +| `src/main.tsx` | Provider setup (WagmiProvider + QueryClient + ConnectKit) | + +## The `useClawSwap` Hook + +The key integration pattern — a thin hook (~80 lines) that bridges the SDK with wagmi: + +```typescript +import { useWalletClient, usePublicClient } from 'wagmi'; +import { ClawSwapClient, isEvmSource } from '@clawswap/sdk'; + +export function useClawSwap() { + const { data: walletClient } = useWalletClient(); + const publicClient = usePublicClient(); + const client = useMemo(() => new ClawSwapClient(), []); + + const executeAndSign = useCallback(async (params) => { + const response = await client.executeSwap(params); + + if (isEvmSource(response)) { + for (const tx of response.transactions) { + const hash = await walletClient.sendTransaction({ + to: tx.to, data: tx.data, value: BigInt(tx.value), + }); + await publicClient.waitForTransactionReceipt({ hash }); + } + } + + return response; + }, [walletClient, publicClient, client]); + + return { client, executeAndSign }; +} +``` + +## Comparison: This vs Raw viem Example + +| Feature | This (wagmi) | Raw viem (`examples/browser/`) | +|---------|-------------|-------------------------------| +| Wallet connection | ConnectKit UI | Manual `window.ethereum` | +| Supported wallets | MetaMask, Coinbase, WalletConnect, etc. | Injected only (MetaMask) | +| Chain switching | Automatic via wagmi | Manual `wallet_switchEthereumChain` | +| Reconnection | Automatic | Manual | +| Dependencies | wagmi, connectkit, @tanstack/react-query | viem only | +| Best for | Production React/Next.js apps | Simple apps, non-React frameworks | diff --git a/examples/browser-wagmi/index.html b/examples/browser-wagmi/index.html new file mode 100644 index 0000000..43d3bd5 --- /dev/null +++ b/examples/browser-wagmi/index.html @@ -0,0 +1,35 @@ + + + + + + ClawSwap SDK - wagmi Example + + + +
+ + + diff --git a/examples/browser-wagmi/package.json b/examples/browser-wagmi/package.json new file mode 100644 index 0000000..e7fdb4d --- /dev/null +++ b/examples/browser-wagmi/package.json @@ -0,0 +1,34 @@ +{ + "name": "@clawswap/example-browser-wagmi", + "version": "0.1.0", + "description": "Browser example for ClawSwap SDK using wagmi v2 + ConnectKit", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "@clawswap/sdk": "workspace:*", + "@tanstack/react-query": "^5.0.0", + "@x402/core": "^2.3.0", + "@x402/evm": "^2.3.0", + "@x402/fetch": "^2.3.0", + "@x402/svm": "^2.3.0", + "@solana/kit": "^5.1.0", + "@solana/web3.js": "^1.95.0", + "connectkit": "^1.8.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "viem": "^2.0.0", + "wagmi": "^2.0.0" + }, + "devDependencies": { + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.0", + "@vitejs/plugin-react": "^4.2.1", + "vite": "^5.0.0", + "typescript": "^5.3.3" + } +} diff --git a/examples/browser-wagmi/src/App.tsx b/examples/browser-wagmi/src/App.tsx new file mode 100644 index 0000000..c85ab75 --- /dev/null +++ b/examples/browser-wagmi/src/App.tsx @@ -0,0 +1,75 @@ +import { useState } from 'react'; +import { useAccount } from 'wagmi'; +import { ConnectKitButton } from 'connectkit'; +import { SwapForm } from './components/SwapForm'; +import { SwapProgress } from './components/SwapProgress'; +import { usePhantomWallet } from './hooks/usePhantomWallet'; +import './styles.css'; + +export function App() { + const { isConnected } = useAccount(); + const phantom = usePhantomWallet(); + const [orderId, setOrderId] = useState(null); + + const anyConnected = isConnected || phantom.connected; + + return ( +
+
+
+

ClawSwap SDK

+

Cross-chain swaps with wagmi v2 + ConnectKit

+
+
+ + {!phantom.connected ? ( + + ) : ( +
+ Phantom + + {phantom.publicKey?.slice(0, 4)}...{phantom.publicKey?.slice(-4)} + +
+ )} +
+
+ +
+ {!anyConnected ? ( +
+

Connect your wallet to get started

+

This example demonstrates ClawSwap SDK integration with wagmi v2 and ConnectKit.

+

Connect MetaMask for Base swaps, Phantom for Solana swaps, or both.

+
+ ) : ( + <> +
+

Swap

+ +
+ + {orderId && ( +
+

Settlement Status

+ +
+ )} + + )} +
+ + +
+ ); +} diff --git a/examples/browser-wagmi/src/components/SwapForm.tsx b/examples/browser-wagmi/src/components/SwapForm.tsx new file mode 100644 index 0000000..d986665 --- /dev/null +++ b/examples/browser-wagmi/src/components/SwapForm.tsx @@ -0,0 +1,227 @@ +import { useState, useEffect } from 'react'; +import { useAccount } from 'wagmi'; +import { type QuoteResponse, type Chain, type Token } from '@clawswap/sdk'; +import { useClawSwap } from '../hooks/useClawSwap'; + +interface PhantomState { + connected: boolean; + publicKey: string | null; + getProvider: () => any; +} + +interface Props { + onSwapInitiated: (orderId: string) => void; + phantom?: PhantomState; +} + +export function SwapForm({ onSwapInitiated, phantom }: Props) { + const { address } = useAccount(); + const { client, getQuote, executeAndSign, error, clearError } = useClawSwap(phantom); + + // Discovery state + const [chains, setChains] = useState([]); + const [sourceTokens, setSourceTokens] = useState([]); + const [destTokens, setDestTokens] = useState([]); + + // Form state + const [sourceChain, setSourceChain] = useState(''); + const [destChain, setDestChain] = useState(''); + const [sourceToken, setSourceToken] = useState(''); + const [destToken, setDestToken] = useState(''); + const [amount, setAmount] = useState('1000000'); + const [recipientAddress, setRecipientAddress] = useState(''); + + // Flow state + const [quote, setQuote] = useState(null); + const [quoteLoading, setQuoteLoading] = useState(false); + const [swapLoading, setSwapLoading] = useState(false); + const [txHashes, setTxHashes] = useState([]); + const [signingStatus, setSigningStatus] = useState(''); + + // Load chains + useEffect(() => { + client.getSupportedChains().then(setChains).catch(console.error); + }, [client]); + + // Load source tokens + useEffect(() => { + if (sourceChain) { + setSourceToken(''); + client.getSupportedTokens(sourceChain).then(setSourceTokens).catch(console.error); + } + }, [sourceChain, client]); + + // Load dest tokens + useEffect(() => { + if (destChain) { + setDestToken(''); + client.getSupportedTokens(destChain).then(setDestTokens).catch(console.error); + } + }, [destChain, client]); + + const handleGetQuote = async (e: React.FormEvent) => { + e.preventDefault(); + if (!address) return; + + setQuoteLoading(true); + setQuote(null); + clearError(); + + try { + const result = await getQuote({ + sourceChainId: sourceChain, + sourceTokenAddress: sourceToken, + destinationChainId: destChain, + destinationTokenAddress: destToken, + amount, + senderAddress: address, + recipientAddress, + }); + setQuote(result); + } finally { + setQuoteLoading(false); + } + }; + + const handleExecuteSwap = async () => { + if (!address || !quote) return; + + setSwapLoading(true); + setTxHashes([]); + setSigningStatus('Requesting swap...'); + clearError(); + + try { + const response = await executeAndSign({ + sourceChainId: sourceChain, + sourceTokenAddress: sourceToken, + destinationChainId: destChain, + destinationTokenAddress: destToken, + amount: quote.sourceAmount, + senderAddress: address, + recipientAddress, + }); + + setSigningStatus(''); + onSwapInitiated(response.orderId); + } catch { + setSigningStatus(''); + } finally { + setSwapLoading(false); + } + }; + + const canQuote = sourceChain && destChain && sourceToken && destToken && amount && address && recipientAddress; + const isExpired = quote ? quote.expiresIn <= 0 : false; + + return ( +
+
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+ +
+ + setAmount(e.target.value)} + placeholder="e.g. 1000000 = 1 USDC" + required + /> +
+ +
+ + + Using connected wallet address +
+ +
+ + setRecipientAddress(e.target.value)} + placeholder="Recipient wallet address on destination chain" + required + /> +
+ + +
+ + {quote && ( +
+

Quote

+
You send:{quote.sourceAmount}
+
You receive:{quote.destinationAmount}
+
Fee:${quote.fees.totalEstimatedFeeUsd.toFixed(2)}
+
Est. time:{quote.estimatedTimeSeconds}s
+
Expires in:{quote.expiresIn}s
+ + +
+ )} + + {txHashes.length > 0 && ( +
+ {txHashes.map((hash, i) => ( + + TX {i + 1}: {hash.slice(0, 10)}...{hash.slice(-8)} + + ))} +
+ )} + + {error &&
{error}
} +
+ ); +} diff --git a/examples/browser-wagmi/src/components/SwapProgress.tsx b/examples/browser-wagmi/src/components/SwapProgress.tsx new file mode 100644 index 0000000..2901783 --- /dev/null +++ b/examples/browser-wagmi/src/components/SwapProgress.tsx @@ -0,0 +1,115 @@ +import { useState, useEffect } from 'react'; +import { type StatusResponse } from '@clawswap/sdk'; +import { useClawSwap } from '../hooks/useClawSwap'; + +interface PhantomState { + connected: boolean; + publicKey: string | null; + getProvider: () => any; +} + +interface Props { + orderId: string; + phantom?: PhantomState; +} + +export function SwapProgress({ orderId, phantom }: Props) { + const { waitForSettlement } = useClawSwap(phantom); + const [status, setStatus] = useState(null); + const [settled, setSettled] = useState(false); + const [error, setError] = useState(null); + + useEffect(() => { + let cancelled = false; + + async function poll() { + try { + const result = await waitForSettlement(orderId, (s) => { + if (!cancelled) setStatus(s); + }); + if (!cancelled) { + setStatus(result); + setSettled(true); + } + } catch (err) { + if (!cancelled) { + setError(err instanceof Error ? err.message : 'Failed to get status'); + } + } + } + + poll(); + + return () => { cancelled = true; }; + }, [orderId, waitForSettlement]); + + if (error) { + return
{error}
; + } + + if (!status) { + return
Loading swap status...
; + } + + const isSuccess = status.status === 'completed' || status.status === 'fulfilled'; + const isFailed = status.status === 'failed'; + + return ( +
+
+ {status.status.toUpperCase()} +
+ +
+
+ Order ID: + {status.orderId} +
+
+ Source: + {status.sourceChainId} - {status.sourceAmount} +
+
+ Destination: + {status.destinationChainId} - {status.destinationAmount} +
+ {status.sourceTxHash && ( +
+ Source TX: + {status.sourceTxHash.slice(0, 10)}...{status.sourceTxHash.slice(-8)} +
+ )} + {status.destinationTxHash && ( +
+ Dest TX: + {status.explorerUrl ? ( + + {status.destinationTxHash.slice(0, 10)}...{status.destinationTxHash.slice(-8)} + + ) : ( + {status.destinationTxHash.slice(0, 10)}...{status.destinationTxHash.slice(-8)} + )} +
+ )} +
+ + {isSuccess && ( +
+ Swap completed! Received {status.destinationAmount} tokens. +
+ )} + + {isFailed && status.failureReason && ( +
+ Swap failed: {status.failureReason} +
+ )} + + {!settled && ( +
+ Waiting for settlement... +
+ )} +
+ ); +} diff --git a/examples/browser-wagmi/src/config/wagmi.ts b/examples/browser-wagmi/src/config/wagmi.ts new file mode 100644 index 0000000..2950fdd --- /dev/null +++ b/examples/browser-wagmi/src/config/wagmi.ts @@ -0,0 +1,17 @@ +import { createConfig, http } from 'wagmi'; +import { base } from 'wagmi/chains'; +import { getDefaultConfig } from 'connectkit'; + +export const config = createConfig( + getDefaultConfig({ + chains: [base], + transports: { + [base.id]: http(), + }, + // WalletConnect project ID — get yours at https://cloud.walletconnect.com + // Optional: only needed for WalletConnect-based wallets + walletConnectProjectId: import.meta.env.VITE_WC_PROJECT_ID || '', + appName: 'ClawSwap Demo', + appDescription: 'Cross-chain swaps powered by the ClawSwap SDK', + }) +); diff --git a/examples/browser-wagmi/src/hooks/useClawSwap.ts b/examples/browser-wagmi/src/hooks/useClawSwap.ts new file mode 100644 index 0000000..4851fc6 --- /dev/null +++ b/examples/browser-wagmi/src/hooks/useClawSwap.ts @@ -0,0 +1,225 @@ +import { useMemo, useState, useCallback } from 'react'; +import { useWalletClient, usePublicClient, useAccount } from 'wagmi'; +import { x402Client } from '@x402/core/client'; +import { registerExactEvmScheme } from '@x402/evm/exact/client'; +import { wrapFetchWithPayment } from '@x402/fetch'; +import { + ClawSwapClient, + isEvmSource, + isSolanaSource, + type QuoteRequest, + type QuoteResponse, + type ExecuteSwapResponse, + type StatusResponse, +} from '@clawswap/sdk'; + +const API_URL = import.meta.env.VITE_CLAWSWAP_API_URL || 'https://api.clawswap.dev'; +const SOLANA_RPC_URL = import.meta.env.VITE_SOLANA_RPC_URL || 'https://api.mainnet-beta.solana.com'; + +export interface TxProgress { + step: number; + total: number; + description: string; + hash?: string; +} + +interface PhantomState { + connected: boolean; + publicKey: string | null; + getProvider: () => any; +} + +export function useClawSwap(phantom?: PhantomState) { + const { data: walletClient } = useWalletClient(); + const publicClient = usePublicClient(); + const { address } = useAccount(); + const [txHashes, setTxHashes] = useState([]); + const [txProgress, setTxProgress] = useState(null); + const [error, setError] = useState(null); + + // Create SDK client with x402 payment (both EVM and SVM schemes) + const client = useMemo(() => { + const x402 = new x402Client(); + let hasScheme = false; + + // Register EVM scheme if MetaMask connected + if (walletClient && address) { + const signer = { + address, + signTypedData: async (typedData: { + domain: Record; + types: Record; + primaryType: string; + message: Record; + }) => { + return walletClient.signTypedData({ + account: address, + domain: typedData.domain as any, + types: typedData.types as any, + primaryType: typedData.primaryType, + message: typedData.message as any, + }); + }, + }; + registerExactEvmScheme(x402, { signer, networks: ['eip155:8453'] }); + hasScheme = true; + } + + // Register SVM scheme if Phantom connected + // Note: SVM scheme registration is async, so we handle it via a wrapper + if (phantom?.connected && phantom.publicKey) { + const phantomPubKey = phantom.publicKey; + const phantomProvider = phantom.getProvider(); + + if (phantomProvider) { + // Lazy-load Solana dependencies and register SVM scheme + // We use a sync placeholder and register async in the background + const registerSvm = async () => { + try { + const { ExactSvmScheme } = await import('@x402/svm/exact/client'); + const { address: toAddress, getTransactionEncoder } = await import('@solana/kit'); + const { VersionedTransaction } = await import('@solana/web3.js'); + + const addr = toAddress(phantomPubKey); + const signer = { + address: addr, + async signTransactions(transactions: any[]) { + const encoder = getTransactionEncoder(); + return Promise.all(transactions.map(async (tx: any) => { + const wireBytes = new Uint8Array(encoder.encode(tx)); + const legacyTx = VersionedTransaction.deserialize(wireBytes); + const signedTx = await phantomProvider.signTransaction(legacyTx); + const keyIndex = signedTx.message.staticAccountKeys.findIndex( + (key: any) => key.toBase58() === phantomPubKey + ); + if (keyIndex < 0) throw new Error('Phantom did not sign the transaction'); + return { [addr]: signedTx.signatures[keyIndex] } as any; + })); + }, + }; + // Register manually to pass rpcUrl config + const scheme = new ExactSvmScheme(signer, { rpcUrl: SOLANA_RPC_URL }); + x402.register('solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp', scheme); + } catch (err) { + console.error('Failed to register SVM payment scheme:', err); + } + }; + registerSvm(); + hasScheme = true; + } + } + + const paymentFetch = wrapFetchWithPayment(fetch.bind(globalThis), x402); + return new ClawSwapClient({ fetch: paymentFetch, baseUrl: API_URL }); + }, [walletClient, address, phantom?.connected, phantom?.publicKey]); + + const getQuote = useCallback(async (params: QuoteRequest): Promise => { + setError(null); + try { + return await client.getQuote(params); + } catch (err) { + const message = err instanceof Error ? err.message : 'Failed to get quote'; + setError(message); + throw err; + } + }, [client]); + + const executeAndSign = useCallback(async (params: QuoteRequest): Promise => { + setTxHashes([]); + setTxProgress(null); + setError(null); + + try { + setTxProgress({ step: 0, total: 0, description: 'Requesting swap...' }); + const response = await client.executeSwap(params); + + if (isEvmSource(response)) { + if (!walletClient || !publicClient) { + throw new Error('MetaMask wallet not connected. Connect MetaMask to execute Base swaps.'); + } + + const hashes: string[] = []; + const total = response.transactions.length; + + for (let i = 0; i < total; i++) { + const tx = response.transactions[i]; + const description = tx.description || `Transaction ${i + 1} of ${total}`; + + setTxProgress({ step: i + 1, total, description: `Signing: ${description}...` }); + + const hash = await walletClient.sendTransaction({ + to: tx.to as `0x${string}`, + data: tx.data as `0x${string}`, + value: BigInt(tx.value), + }); + + setTxProgress({ step: i + 1, total, description: `Confirming: ${description}...`, hash }); + await publicClient.waitForTransactionReceipt({ hash }); + + hashes.push(hash); + setTxHashes([...hashes]); + } + + setTxProgress(null); + } else if (isSolanaSource(response)) { + // Solana source: sign with Phantom and submit + const phantomProvider = phantom?.getProvider(); + if (!phantom?.connected || !phantomProvider) { + throw new Error('Phantom wallet not connected. Connect Phantom to execute Solana swaps.'); + } + + const { Transaction, Connection } = await import('@solana/web3.js'); + + setTxProgress({ step: 1, total: 1, description: 'Signing Solana transaction with Phantom...' }); + + const txBuffer = Uint8Array.from(atob(response.transaction), c => c.charCodeAt(0)); + const transaction = Transaction.from(txBuffer); + const signedTx = await phantomProvider.signTransaction(transaction); + + setTxProgress({ step: 1, total: 1, description: 'Submitting to Solana...' }); + + const connection = new Connection(SOLANA_RPC_URL, 'confirmed'); + const serialized = signedTx.serialize(); + const signature = await connection.sendRawTransaction(serialized, { + skipPreflight: false, + preflightCommitment: 'confirmed', + }); + + setTxHashes([signature]); + setTxProgress({ step: 1, total: 1, description: 'Waiting for confirmation...', hash: signature }); + + await connection.confirmTransaction(signature, 'confirmed'); + setTxProgress(null); + } + + return response; + } catch (err) { + setTxProgress(null); + const message = err instanceof Error ? err.message : 'Swap failed'; + setError(message); + throw err; + } + }, [walletClient, publicClient, client, phantom]); + + const waitForSettlement = useCallback(async ( + orderId: string, + onStatusUpdate?: (status: StatusResponse) => void, + ): Promise => { + return client.waitForSettlement(orderId, { + timeout: 300_000, + interval: 3000, + onStatusUpdate, + }); + }, [client]); + + return { + client, + getQuote, + executeAndSign, + waitForSettlement, + txHashes, + txProgress, + error, + clearError: () => setError(null), + }; +} diff --git a/examples/browser-wagmi/src/hooks/usePhantomWallet.ts b/examples/browser-wagmi/src/hooks/usePhantomWallet.ts new file mode 100644 index 0000000..65259b7 --- /dev/null +++ b/examples/browser-wagmi/src/hooks/usePhantomWallet.ts @@ -0,0 +1,60 @@ +import { useState, useCallback, useEffect } from 'react'; + +interface PhantomProvider { + connect(): Promise<{ publicKey: { toBase58(): string } }>; + disconnect(): Promise; + signTransaction(transaction: T): Promise; + signAllTransactions(transactions: T[]): Promise; + isConnected: boolean; + publicKey: { toBase58(): string } | null; +} + +declare global { + interface Window { + phantom?: { solana?: PhantomProvider }; + } +} + +export function usePhantomWallet() { + const [connected, setConnected] = useState(false); + const [publicKey, setPublicKey] = useState(null); + + const getProvider = useCallback((): PhantomProvider | null => { + return window.phantom?.solana ?? null; + }, []); + + // Auto-detect existing connection + useEffect(() => { + const phantom = getProvider(); + if (phantom?.isConnected && phantom.publicKey) { + setPublicKey(phantom.publicKey.toBase58()); + setConnected(true); + } + }, [getProvider]); + + const connect = useCallback(async () => { + const provider = getProvider(); + if (!provider) { + alert('Please install Phantom wallet'); + return; + } + try { + const response = await provider.connect(); + setPublicKey(response.publicKey.toBase58()); + setConnected(true); + } catch (err) { + console.error('Failed to connect Phantom:', err); + } + }, [getProvider]); + + const disconnect = useCallback(async () => { + const provider = getProvider(); + if (provider) { + await provider.disconnect(); + } + setPublicKey(null); + setConnected(false); + }, [getProvider]); + + return { connected, publicKey, connect, disconnect, getProvider }; +} diff --git a/examples/browser-wagmi/src/main.tsx b/examples/browser-wagmi/src/main.tsx new file mode 100644 index 0000000..65cc694 --- /dev/null +++ b/examples/browser-wagmi/src/main.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import { WagmiProvider } from 'wagmi'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { ConnectKitProvider } from 'connectkit'; +import { config } from './config/wagmi'; +import { App } from './App'; + +const queryClient = new QueryClient(); + +ReactDOM.createRoot(document.getElementById('root')!).render( + + + + + + + + + +); diff --git a/examples/browser-wagmi/src/styles.css b/examples/browser-wagmi/src/styles.css new file mode 100644 index 0000000..a6256db --- /dev/null +++ b/examples/browser-wagmi/src/styles.css @@ -0,0 +1,407 @@ +/* Layout */ +.app { + max-width: 720px; + margin: 0 auto; +} + +.header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 24px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 16px; + margin-bottom: 24px; +} + +.header h1 { + font-size: 1.5rem; + margin-bottom: 4px; +} + +.header p { + font-size: 0.85rem; + color: #94a3b8; +} + +.main { + display: flex; + flex-direction: column; + gap: 20px; +} + +.card { + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 16px; + padding: 24px; +} + +.card h2 { + font-size: 1.2rem; + margin-bottom: 20px; + color: #f1f5f9; +} + +.connect-prompt { + text-align: center; + padding: 60px 20px; + background: rgba(255, 255, 255, 0.03); + border: 1px dashed rgba(255, 255, 255, 0.15); + border-radius: 16px; +} + +.connect-prompt h2 { + margin-bottom: 12px; + color: #f1f5f9; +} + +.connect-prompt p { + color: #94a3b8; + margin-top: 8px; + font-size: 0.9rem; +} + +/* Forms */ +.swap-form { + display: flex; + flex-direction: column; + gap: 16px; +} + +.form-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 12px; +} + +.form-group { + display: flex; + flex-direction: column; + gap: 6px; + margin-bottom: 4px; +} + +.form-group label { + font-size: 0.8rem; + font-weight: 600; + color: #94a3b8; + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.form-group select, +.form-group input { + padding: 10px 12px; + background: rgba(255, 255, 255, 0.07); + border: 1px solid rgba(255, 255, 255, 0.15); + border-radius: 8px; + color: #e2e8f0; + font-size: 0.95rem; + transition: border-color 0.2s; +} + +.form-group select:focus, +.form-group input:focus { + outline: none; + border-color: #6366f1; +} + +.form-group select:disabled, +.form-group input:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.form-group select option { + background: #1e293b; + color: #e2e8f0; +} + +.form-group small { + font-size: 0.75rem; + color: #64748b; +} + +/* Buttons */ +.btn { + padding: 12px 20px; + border: none; + border-radius: 10px; + font-size: 0.95rem; + font-weight: 600; + cursor: pointer; + transition: all 0.2s; + width: 100%; +} + +.btn:disabled { + opacity: 0.4; + cursor: not-allowed; +} + +.btn-primary { + background: #6366f1; + color: white; + margin-top: 12px; +} + +.btn-primary:hover:not(:disabled) { + background: #4f46e5; + transform: translateY(-1px); +} + +.btn-secondary { + background: rgba(255, 255, 255, 0.1); + color: #e2e8f0; + border: 1px solid rgba(255, 255, 255, 0.2); +} + +.btn-secondary:hover:not(:disabled) { + background: rgba(255, 255, 255, 0.15); +} + +/* Quote card */ +.quote-card { + margin-top: 16px; + padding: 16px; + background: rgba(99, 102, 241, 0.1); + border: 1px solid rgba(99, 102, 241, 0.3); + border-radius: 12px; +} + +.quote-card h3 { + font-size: 0.9rem; + color: #a5b4fc; + margin-bottom: 12px; + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.quote-row { + display: flex; + justify-content: space-between; + align-items: center; + padding: 6px 0; + font-size: 0.9rem; +} + +.quote-row span:first-child { + color: #94a3b8; +} + +.quote-row.warning { + color: #fbbf24; +} + +/* Transaction list */ +.tx-list { + display: flex; + flex-direction: column; + gap: 6px; + margin-top: 12px; +} + +.tx-link { + color: #818cf8; + font-family: 'Monaco', 'Courier New', monospace; + font-size: 0.85rem; + text-decoration: none; +} + +.tx-link:hover { + text-decoration: underline; + color: #a5b4fc; +} + +/* Swap Progress */ +.swap-progress { + display: flex; + flex-direction: column; + gap: 16px; +} + +.status-indicator { + display: inline-block; + padding: 8px 16px; + border-radius: 8px; + font-weight: 700; + font-size: 0.85rem; + letter-spacing: 0.05em; + text-align: center; +} + +.status-indicator.success { + background: rgba(34, 197, 94, 0.15); + color: #4ade80; + border: 1px solid rgba(34, 197, 94, 0.3); +} + +.status-indicator.failed { + background: rgba(239, 68, 68, 0.15); + color: #f87171; + border: 1px solid rgba(239, 68, 68, 0.3); +} + +.status-indicator.pending { + background: rgba(99, 102, 241, 0.15); + color: #a5b4fc; + border: 1px solid rgba(99, 102, 241, 0.3); +} + +.progress-details { + background: rgba(255, 255, 255, 0.03); + padding: 12px; + border-radius: 8px; +} + +.progress-row { + display: flex; + justify-content: space-between; + align-items: center; + padding: 6px 0; + font-size: 0.85rem; + border-bottom: 1px solid rgba(255, 255, 255, 0.05); +} + +.progress-row:last-child { + border-bottom: none; +} + +.progress-row span:first-child { + color: #94a3b8; +} + +.progress-row code { + background: rgba(255, 255, 255, 0.07); + padding: 2px 8px; + border-radius: 4px; + font-size: 0.8rem; +} + +.progress-row a { + color: #818cf8; + text-decoration: none; + font-family: 'Monaco', 'Courier New', monospace; + font-size: 0.8rem; +} + +.progress-row a:hover { + text-decoration: underline; +} + +.progress-loading { + text-align: center; + padding: 20px; + color: #94a3b8; +} + +/* Banners */ +.success-banner { + background: rgba(34, 197, 94, 0.15); + color: #4ade80; + border: 1px solid rgba(34, 197, 94, 0.3); + padding: 12px; + border-radius: 8px; + font-weight: 500; +} + +.error-banner { + background: rgba(239, 68, 68, 0.15); + color: #f87171; + border: 1px solid rgba(239, 68, 68, 0.3); + padding: 12px; + border-radius: 8px; + margin-top: 8px; +} + +.polling-badge { + text-align: center; + padding: 8px; + color: #94a3b8; + font-size: 0.85rem; +} + +/* Wallet buttons */ +.wallet-buttons { + display: flex; + align-items: center; + gap: 10px; +} + +.btn-phantom { + padding: 10px 16px; + border: none; + border-radius: 10px; + font-size: 0.9rem; + font-weight: 600; + cursor: pointer; + background: linear-gradient(135deg, #ab9ff2 0%, #7c3aed 100%); + color: white; + transition: all 0.2s; + width: auto; +} + +.btn-phantom:hover { + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(171, 159, 242, 0.4); +} + +.phantom-badge { + display: inline-flex; + align-items: center; + gap: 8px; + background: rgba(171, 159, 242, 0.15); + border: 1px solid rgba(171, 159, 242, 0.3); + padding: 8px 14px; + border-radius: 10px; +} + +.phantom-label { + color: #ab9ff2; + font-size: 0.8rem; + font-weight: 600; +} + +.phantom-address { + font-family: 'Monaco', 'Courier New', monospace; + font-size: 0.8rem; + color: #e2e8f0; +} + +/* Footer */ +.footer { + text-align: center; + padding: 24px; + margin-top: 32px; + color: #64748b; + font-size: 0.85rem; +} + +.footer a { + color: #94a3b8; + text-decoration: none; +} + +.footer a:hover { + color: #e2e8f0; +} + +/* Responsive */ +@media (max-width: 640px) { + .header { + flex-direction: column; + gap: 16px; + text-align: center; + } + + .wallet-buttons { + flex-direction: column; + width: 100%; + } + + .form-grid { + grid-template-columns: 1fr; + } +} diff --git a/examples/browser-wagmi/src/vite-env.d.ts b/examples/browser-wagmi/src/vite-env.d.ts new file mode 100644 index 0000000..e91619a --- /dev/null +++ b/examples/browser-wagmi/src/vite-env.d.ts @@ -0,0 +1,10 @@ +/// + +interface ImportMetaEnv { + readonly VITE_CLAWSWAP_API_URL?: string; + readonly VITE_SOLANA_RPC_URL?: string; +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +} \ No newline at end of file diff --git a/examples/browser-wagmi/tsconfig.json b/examples/browser-wagmi/tsconfig.json new file mode 100644 index 0000000..d236ad5 --- /dev/null +++ b/examples/browser-wagmi/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "jsx": "react-jsx", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/examples/browser-wagmi/vite.config.ts b/examples/browser-wagmi/vite.config.ts new file mode 100644 index 0000000..6e7dcc4 --- /dev/null +++ b/examples/browser-wagmi/vite.config.ts @@ -0,0 +1,18 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + define: { + 'process.env': {}, + global: 'globalThis', + }, + optimizeDeps: { + esbuildOptions: { + target: 'es2020', + }, + }, + server: { + port: 5174, + }, +}); diff --git a/examples/browser/package.json b/examples/browser/package.json index cf40fcc..be20fdc 100644 --- a/examples/browser/package.json +++ b/examples/browser/package.json @@ -14,6 +14,9 @@ "@x402/fetch": "^2.3.0", "@x402/core": "^2.3.0", "@x402/evm": "^2.3.0", + "@x402/svm": "^2.3.0", + "@solana/kit": "^5.1.0", + "@solana/web3.js": "^1.95.0", "react": "^18.2.0", "react-dom": "^18.2.0", "viem": "^2.0.0" diff --git a/examples/browser/src/App.tsx b/examples/browser/src/App.tsx index 8d04a5d..e4b2a69 100644 --- a/examples/browser/src/App.tsx +++ b/examples/browser/src/App.tsx @@ -1,7 +1,7 @@ import { useState, useEffect } from 'react'; -import { ClawSwapClient, QuoteResponse } from '@clawswap/sdk'; +import { ClawSwapClient } from '@clawswap/sdk'; import { useWallet } from './hooks/useWallet'; -import { QuoteForm } from './components/QuoteForm'; +import { QuoteForm, SwapParams } from './components/QuoteForm'; import { SwapButton } from './components/SwapButton'; import { StatusPanel } from './components/StatusPanel'; import './styles.css'; @@ -9,17 +9,24 @@ import './styles.css'; const API_URL = import.meta.env.VITE_CLAWSWAP_API_URL || 'https://api.clawswap.dev'; export function App() { - const { connected, address, connect, fetchWithPayment } = useWallet(); + const { + evmConnected, evmAddress, connectEvm, + walletClient, publicClient, ensureBaseChain, + solanaConnected, solanaAddress, connectSolana, + fetchWithPayment, + } = useWallet(); + const [client, setClient] = useState(null); - const [quote, setQuote] = useState(null); + const [swapParams, setSwapParams] = useState(null); const [swapId, setSwapId] = useState(null); + const anyConnected = evmConnected || solanaConnected; + // Create client with or without payment useEffect(() => { if (fetchWithPayment) { setClient(new ClawSwapClient({ fetch: fetchWithPayment, baseUrl: API_URL })); } else { - // Create client without payment for free endpoints setClient(new ClawSwapClient({ baseUrl: API_URL })); } }, [fetchWithPayment]); @@ -27,18 +34,30 @@ export function App() { return (
-

🐾 ClawSwap SDK Demo

+

ClawSwap SDK Demo

Cross-chain swaps powered by AI agents

- {!connected ? ( - - ) : ( -
- - {address?.slice(0, 6)}...{address?.slice(-4)} -
- )} +
+ {!evmConnected ? ( + + ) : ( +
+ MetaMask + {evmAddress?.slice(0, 6)}...{evmAddress?.slice(-4)} +
+ )} + {!solanaConnected ? ( + + ) : ( +
+ Phantom + {solanaAddress?.slice(0, 4)}...{solanaAddress?.slice(-4)} +
+ )} +
{!client ? ( @@ -47,19 +66,32 @@ export function App() {

Get Quote

- +
- {quote && ( + {swapParams && (

Execute Swap

- {!connected ? ( -

Connect your wallet to execute the swap

+ {!anyConnected ? ( +

Connect a wallet to execute the swap

) : ( )} diff --git a/examples/browser/src/components/QuoteForm.tsx b/examples/browser/src/components/QuoteForm.tsx index 8a0de4a..e364da0 100644 --- a/examples/browser/src/components/QuoteForm.tsx +++ b/examples/browser/src/components/QuoteForm.tsx @@ -1,13 +1,23 @@ import { useState, useEffect } from 'react'; import { ClawSwapClient, Chain, Token, QuoteResponse } from '@clawswap/sdk'; +export interface SwapParams { + quote: QuoteResponse; + sourceChainId: string; + sourceTokenAddress: string; + destinationChainId: string; + destinationTokenAddress: string; + senderAddress: string; + recipientAddress: string; +} + interface Props { client: ClawSwapClient; walletAddress?: string; - onQuote?: (quote: QuoteResponse) => void; + onSwapParams?: (params: SwapParams) => void; } -export function QuoteForm({ client, walletAddress, onQuote }: Props) { +export function QuoteForm({ client, walletAddress, onSwapParams }: Props) { const [chains, setChains] = useState([]); const [sourceChain, setSourceChain] = useState(''); const [destChain, setDestChain] = useState(''); @@ -75,7 +85,15 @@ export function QuoteForm({ client, walletAddress, onQuote }: Props) { }); setQuote(result); - onQuote?.(result); + onSwapParams?.({ + quote: result, + sourceChainId: sourceChain, + sourceTokenAddress: sourceToken, + destinationChainId: destChain, + destinationTokenAddress: destToken, + senderAddress, + recipientAddress, + }); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to get quote'); } finally { @@ -212,7 +230,7 @@ export function QuoteForm({ client, walletAddress, onQuote }: Props) {
Quote ID: - {quote.id} + {quote.quoteId}
You send: @@ -224,14 +242,14 @@ export function QuoteForm({ client, walletAddress, onQuote }: Props) {
Total fee: - ${quote.fees.totalFeeUsd} + ${quote.fees.totalEstimatedFeeUsd.toFixed(2)}
Estimated time: {quote.estimatedTimeSeconds}s
- ⏱ Expires in: + Expires in: {quote.expiresIn}s
diff --git a/examples/browser/src/components/StatusPanel.tsx b/examples/browser/src/components/StatusPanel.tsx index 7c8bcbc..5591974 100644 --- a/examples/browser/src/components/StatusPanel.tsx +++ b/examples/browser/src/components/StatusPanel.tsx @@ -29,7 +29,7 @@ export function StatusPanel({ client, swapId }: Props) { setStatus(result); // Stop polling on terminal status - if (['completed', 'failed', 'expired'].includes(result.status)) { + if (['completed', 'fulfilled', 'failed', 'cancelled'].includes(result.status)) { setPolling(false); } } catch (err) { @@ -46,9 +46,10 @@ export function StatusPanel({ client, swapId }: Props) { return
Loading status...
; } - const statusClass = status.status === 'completed' ? 'success' : + const isSuccess = status.status === 'completed' || status.status === 'fulfilled'; + const statusClass = isSuccess ? 'success' : status.status === 'failed' ? 'error' : - status.status === 'expired' ? 'warning' : + status.status === 'cancelled' ? 'warning' : 'info'; return ( @@ -59,8 +60,8 @@ export function StatusPanel({ client, swapId }: Props) {
- Swap ID: - {status.swapId} + Order ID: + {status.orderId}
Source: @@ -70,46 +71,47 @@ export function StatusPanel({ client, swapId }: Props) { Destination: {status.destinationChainId}: {status.destinationAmount}
+ {status.sourceTxHash && ( +
+ Source TX: + {status.sourceTxHash.slice(0, 10)}...{status.sourceTxHash.slice(-8)} +
+ )} + {status.destinationTxHash && ( +
+ Destination TX: + {status.explorerUrl ? ( + + {status.destinationTxHash.slice(0, 10)}...{status.destinationTxHash.slice(-8)} + + ) : ( + {status.destinationTxHash.slice(0, 10)}...{status.destinationTxHash.slice(-8)} + )} +
+ )} + {status.estimatedCompletionTime && ( +
+ Estimated completion: + {new Date(status.estimatedCompletionTime).toLocaleTimeString()} +
+ )}
- {status.transactions && status.transactions.length > 0 && ( -
-

Transactions

- {status.transactions.map((tx, i) => ( -
-
- {tx.chainId} - {tx.status} -
-
- {tx.explorerUrl ? ( - - {tx.txHash.slice(0, 10)}...{tx.txHash.slice(-8)} - - ) : ( - {tx.txHash.slice(0, 10)}...{tx.txHash.slice(-8)} - )} -
-
- ))} -
- )} - - {status.status === 'completed' && ( + {isSuccess && (
- ✨ Swap completed successfully! You received {status.destinationAmount} tokens. + Swap completed successfully! You received {status.destinationAmount} tokens.
)} {status.status === 'failed' && status.failureReason && (
- ❌ Swap failed: {status.failureReason} + Swap failed: {status.failureReason}
)} {polling && (
- + Polling for updates...
)} diff --git a/examples/browser/src/components/SwapButton.tsx b/examples/browser/src/components/SwapButton.tsx index 61da44a..084209d 100644 --- a/examples/browser/src/components/SwapButton.tsx +++ b/examples/browser/src/components/SwapButton.tsx @@ -1,5 +1,8 @@ import { useState } from 'react'; -import { ClawSwapClient, QuoteResponse } from '@clawswap/sdk'; +import { ClawSwapClient, QuoteResponse, isEvmSource, isSolanaSource } from '@clawswap/sdk'; +import type { WalletClient, PublicClient } from 'viem'; + +const SOLANA_RPC_URL = import.meta.env.VITE_SOLANA_RPC_URL || 'https://api.mainnet-beta.solana.com'; interface Props { client: ClawSwapClient; @@ -10,9 +13,19 @@ interface Props { destinationTokenAddress: string; senderAddress: string; destinationAddress: string; + walletClient: WalletClient | null; + publicClient: PublicClient | null; + ensureBaseChain: () => Promise; + solanaConnected: boolean; onSwapInitiated?: (orderId: string) => void; } +interface TxResult { + hash: string; + description?: string; + explorer?: string; +} + export function SwapButton({ client, quote, @@ -22,29 +35,114 @@ export function SwapButton({ destinationTokenAddress, senderAddress, destinationAddress, + walletClient, + publicClient, + ensureBaseChain, + solanaConnected, onSwapInitiated }: Props) { const [loading, setLoading] = useState(false); + const [status, setStatus] = useState(''); const [error, setError] = useState(''); + const [txResults, setTxResults] = useState([]); const handleExecuteSwap = async () => { setLoading(true); setError(''); + setStatus('Requesting swap...'); + setTxResults([]); try { - // Execute swap with v2 API (no need for getTokenInfo - API handles it) const executeResponse = await client.executeSwap({ - sourceChainId: sourceChainId, - sourceTokenAddress: sourceTokenAddress, - destinationChainId: destinationChainId, - destinationTokenAddress: destinationTokenAddress, + sourceChainId, + sourceTokenAddress, + destinationChainId, + destinationTokenAddress, amount: quote.sourceAmount, - senderAddress: senderAddress, + senderAddress, recipientAddress: destinationAddress, + slippageTolerance: 0.01, }); - console.log('Swap initiated:', executeResponse); - onSwapInitiated?.(executeResponse.metadata.orderId); + console.log('Swap response:', executeResponse); + + if (isEvmSource(executeResponse)) { + // EVM source (Base -> Solana): sign and submit each transaction + if (!walletClient || !publicClient) { + setError('MetaMask wallet not connected. Connect MetaMask to execute Base swaps.'); + setLoading(false); + return; + } + + await ensureBaseChain(); + + for (let i = 0; i < executeResponse.transactions.length; i++) { + const tx = executeResponse.transactions[i]; + const stepLabel = tx.description || `Transaction ${i + 1} of ${executeResponse.transactions.length}`; + setStatus(`Signing: ${stepLabel}...`); + + const txHash = await walletClient.sendTransaction({ + to: tx.to as `0x${string}`, + data: tx.data as `0x${string}`, + value: BigInt(tx.value), + }); + + setStatus(`Waiting for confirmation: ${stepLabel}...`); + await publicClient.waitForTransactionReceipt({ hash: txHash }); + + setTxResults(prev => [...prev, { + hash: txHash, + description: tx.description, + explorer: `https://basescan.org/tx/${txHash}`, + }]); + console.log(`TX confirmed: ${txHash}`); + } + + setStatus('Transactions submitted! Waiting for cross-chain settlement...'); + } else if (isSolanaSource(executeResponse)) { + // Solana source (Solana -> Base): sign with Phantom and submit + if (!solanaConnected || !window.phantom?.solana) { + setError('Phantom wallet not connected. Connect Phantom to execute Solana swaps.'); + setLoading(false); + return; + } + + const phantom = window.phantom.solana; + const { Transaction, Connection } = await import('@solana/web3.js'); + + setStatus('Signing Solana transaction with Phantom...'); + + // Decode the base64 transaction from the API + const txBuffer = Uint8Array.from(atob(executeResponse.transaction), c => c.charCodeAt(0)); + const transaction = Transaction.from(txBuffer); + + // Have Phantom sign it + const signedTx = await phantom.signTransaction(transaction); + + setStatus('Submitting transaction to Solana...'); + + const connection = new Connection(SOLANA_RPC_URL, 'confirmed'); + + const serialized = signedTx.serialize(); + const signature = await connection.sendRawTransaction(serialized, { + skipPreflight: false, + preflightCommitment: 'confirmed', + }); + + setTxResults([{ + hash: signature, + description: 'Solana swap transaction', + explorer: `https://solscan.io/tx/${signature}`, + }]); + + setStatus('Transaction submitted! Waiting for confirmation...'); + + // Wait for confirmation + await connection.confirmTransaction(signature, 'confirmed'); + setStatus('Transaction confirmed! Waiting for cross-chain settlement...'); + } + + onSwapInitiated?.(executeResponse.orderId); } catch (err) { console.error('Swap failed:', err); setError(err instanceof Error ? err.message : 'Failed to execute swap'); @@ -59,13 +157,21 @@ export function SwapButton({ return (
+
+ You send: + {quote.sourceAmount} +
+
+ You receive: + {quote.destinationAmount} +
Destination: - {destinationAddress} + {destinationAddress.slice(0, 10)}...{destinationAddress.slice(-6)}
- Fee (via x402): - ${parseFloat(quote.fees.totalFeeUsd).toFixed(2)} USDC + Estimated fee: + ${quote.fees.totalEstimatedFeeUsd.toFixed(2)}
@@ -74,21 +180,36 @@ export function SwapButton({ className="btn btn-primary btn-large" disabled={loading || isExpired} > - {loading ? '⏳ Executing swap...' : isExpired ? '❌ Quote expired' : '🚀 Execute Swap'} + {loading ? 'Processing...' : isExpired ? 'Quote expired' : 'Execute Swap'} + {status &&
{status}
} + {isExpired && (

- ⚠️ This quote has expired. Please get a new quote. + This quote has expired. Please get a new quote.

)} - {error &&
{error}
} + {txResults.length > 0 && ( +
+

Transactions

+ {txResults.map((tx, i) => ( +
+ {tx.description || `Transaction ${i + 1}`}: + + {tx.hash.slice(0, 10)}...{tx.hash.slice(-8)} + +
+ ))} +
+ )} -

- ℹ️ This will charge ${parseFloat(quote.fees.totalFeeUsd).toFixed(2)} USDC from your wallet via x402. - Make sure you have sufficient USDC balance. -

+ {error &&
{error}
}
); } diff --git a/examples/browser/src/hooks/useWallet.ts b/examples/browser/src/hooks/useWallet.ts index 1fdbbb0..7c585a3 100644 --- a/examples/browser/src/hooks/useWallet.ts +++ b/examples/browser/src/hooks/useWallet.ts @@ -1,76 +1,238 @@ -import { useState, useEffect } from 'react'; +import { useState, useEffect, useCallback, useRef } from 'react'; import { registerExactEvmScheme } from '@x402/evm/exact/client'; import { wrapFetchWithPayment } from '@x402/fetch'; -import { createWalletClient, custom, type Address } from 'viem'; +import { createWalletClient, createPublicClient, custom, http, type WalletClient, type PublicClient, type Address } from 'viem'; import { base } from 'viem/chains'; -// Extend Window interface for ethereum +// Phantom wallet provider type +interface PhantomProvider { + connect(): Promise<{ publicKey: { toBase58(): string } }>; + disconnect(): Promise; + signTransaction(transaction: T): Promise; + signAllTransactions(transactions: T[]): Promise; + isConnected: boolean; + publicKey: { toBase58(): string } | null; +} + declare global { interface Window { ethereum?: any; + phantom?: { solana?: PhantomProvider }; } } +const BASE_CHAIN_ID = '0x2105'; // 8453 in hex +const SOLANA_RPC_URL = import.meta.env.VITE_SOLANA_RPC_URL || 'https://api.mainnet-beta.solana.com'; + export function useWallet() { - const [connected, setConnected] = useState(false); - const [address, setAddress] = useState
(null); + // EVM wallet state + const [evmConnected, setEvmConnected] = useState(false); + const [evmAddress, setEvmAddress] = useState
(null); + const [walletClient, setWalletClient] = useState(null); + const [publicClient, setPublicClient] = useState(null); + + // Solana wallet state + const [solanaConnected, setSolanaConnected] = useState(false); + const [solanaAddress, setSolanaAddress] = useState(null); + + // Payment const [fetchWithPayment, setFetchWithPayment] = useState(null); - // Check if wallet is already connected on mount + // Track wallet state for payment rebuild + const evmSignerRef = useRef<{ address: Address; signTypedData: any } | null>(null); + + // Check if MetaMask already connected on mount + useEffect(() => { + if (!window.ethereum) return; + window.ethereum.request({ method: 'eth_accounts' }) + .then((accounts: string[]) => { + if (accounts.length > 0) connectEvm(); + }) + .catch((err: unknown) => console.error('Failed to check wallet:', err)); + }, []); + + // Check if Phantom already connected on mount + useEffect(() => { + const phantom = window.phantom?.solana; + if (phantom?.isConnected && phantom.publicKey) { + setSolanaAddress(phantom.publicKey.toBase58()); + setSolanaConnected(true); + } + }, []); + + // Rebuild x402 payment whenever wallet connections change useEffect(() => { - if (window.ethereum) { - window.ethereum.request({ method: 'eth_accounts' }).then((accounts: string[]) => { - if (accounts.length > 0) { - // Auto-connect if already authorized - connect(); + rebuildPaymentFetch(); + }, [evmConnected, solanaConnected]); + + const ensureBaseChain = useCallback(async () => { + if (!window.ethereum) return; + const currentChainId = await window.ethereum.request({ method: 'eth_chainId' }); + if (currentChainId !== BASE_CHAIN_ID) { + try { + await window.ethereum.request({ + method: 'wallet_switchEthereumChain', + params: [{ chainId: BASE_CHAIN_ID }], + }); + } catch (switchError: any) { + if (switchError.code === 4902) { + await window.ethereum.request({ + method: 'wallet_addEthereumChain', + params: [{ + chainId: BASE_CHAIN_ID, + chainName: 'Base', + nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 }, + rpcUrls: ['https://mainnet.base.org'], + blockExplorerUrls: ['https://basescan.org'], + }], + }); + } else { + throw switchError; } - }); + } } }, []); - const connect = async () => { + const rebuildPaymentFetch = async () => { + const { x402Client } = await import('@x402/core/client'); + const client = new x402Client(); + + // Register EVM scheme if MetaMask connected + if (evmSignerRef.current) { + registerExactEvmScheme(client, { + signer: evmSignerRef.current, + networks: ['eip155:8453'], + }); + } + + // Register SVM scheme if Phantom connected + const phantom = window.phantom?.solana; + if (solanaConnected && solanaAddress && phantom) { + try { + const { ExactSvmScheme } = await import('@x402/svm/exact/client'); + const { address: toAddress, getTransactionEncoder } = await import('@solana/kit'); + const { VersionedTransaction } = await import('@solana/web3.js'); + + const addr = toAddress(solanaAddress); + const pubKeyStr = solanaAddress; + + const signer = { + address: addr, + async signTransactions(transactions: any[]) { + const encoder = getTransactionEncoder(); + return Promise.all(transactions.map(async (tx: any) => { + // Serialize v2 Transaction to wire bytes, cast for VersionedTransaction compat + const wireBytes = new Uint8Array(encoder.encode(tx)); + // Convert to v1 VersionedTransaction for Phantom + const legacyTx = VersionedTransaction.deserialize(wireBytes); + // Have Phantom sign it + const signedTx = await phantom.signTransaction(legacyTx); + // Find our key index and extract signature + const keyIndex = signedTx.message.staticAccountKeys.findIndex( + (key: any) => key.toBase58() === pubKeyStr + ); + if (keyIndex < 0) { + throw new Error('Phantom did not sign the transaction'); + } + return { [addr]: signedTx.signatures[keyIndex] } as any; + })); + }, + }; + + // Register manually to pass rpcUrl config (registerExactSvmScheme doesn't forward it) + const scheme = new ExactSvmScheme(signer, { rpcUrl: SOLANA_RPC_URL }); + client.register('solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp', scheme); + } catch (err) { + console.error('Failed to register SVM payment scheme:', err); + } + } + + const wrapped = wrapFetchWithPayment(fetch.bind(globalThis), client); + setFetchWithPayment(() => wrapped); + }; + + const connectEvm = async () => { if (!window.ethereum) { alert('Please install MetaMask or another Web3 wallet'); return; } try { - // Request account access - const accounts = await window.ethereum.request({ - method: 'eth_requestAccounts', - }); - - if (!accounts || accounts.length === 0) { - throw new Error('No accounts found'); - } + const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' }); + if (!accounts || accounts.length === 0) throw new Error('No accounts found'); const account = accounts[0] as Address; - setAddress(account); + setEvmAddress(account); + + await ensureBaseChain(); - // Create wallet client - const walletClient = createWalletClient({ + const wc = createWalletClient({ + account, chain: base, transport: custom(window.ethereum), }); + setWalletClient(wc as any); - // Setup x402 payment (lazy load for browser compatibility) - const { x402Client } = await import('@x402/core'); - const client = new x402Client(); - registerExactEvmScheme(client, { - signer: { address: account }, - network: 'eip155:8453', // Base mainnet - }); + const pc = createPublicClient({ chain: base, transport: http() }); + setPublicClient(pc); - const wrapped = wrapFetchWithPayment(fetch, client); - setFetchWithPayment(() => wrapped); - setConnected(true); + // Create EVM signer for x402 + evmSignerRef.current = { + address: account, + signTypedData: async (typedData: { + domain: Record; + types: Record; + primaryType: string; + message: Record; + }) => { + return wc.signTypedData({ + account, + domain: typedData.domain as any, + types: typedData.types as any, + primaryType: typedData.primaryType, + message: typedData.message as any, + }); + }, + }; - console.log('Wallet connected:', account); + setEvmConnected(true); } catch (error) { - console.error('Failed to connect wallet:', error); - alert(`Failed to connect wallet: ${error instanceof Error ? error.message : 'Unknown error'}`); + console.error('Failed to connect MetaMask:', error); + alert(`Failed to connect MetaMask: ${error instanceof Error ? error.message : 'Unknown error'}`); } }; - return { connected, address, connect, fetchWithPayment }; + const connectSolana = async () => { + const phantom = window.phantom?.solana; + if (!phantom) { + alert('Please install Phantom wallet'); + return; + } + + try { + const response = await phantom.connect(); + const pubKey = response.publicKey.toBase58(); + setSolanaAddress(pubKey); + setSolanaConnected(true); + } catch (error) { + console.error('Failed to connect Phantom:', error); + alert(`Failed to connect Phantom: ${error instanceof Error ? error.message : 'Unknown error'}`); + } + }; + + return { + // EVM + evmConnected, + evmAddress, + connectEvm, + walletClient, + publicClient, + ensureBaseChain, + // Solana + solanaConnected, + solanaAddress, + connectSolana, + // Payment + fetchWithPayment, + }; } diff --git a/examples/browser/src/styles.css b/examples/browser/src/styles.css index c06268e..c6dd977 100644 --- a/examples/browser/src/styles.css +++ b/examples/browser/src/styles.css @@ -25,6 +25,13 @@ margin-bottom: 20px; } +.wallet-buttons { + display: flex; + gap: 10px; + justify-content: center; + flex-wrap: wrap; +} + .wallet-info { display: inline-flex; align-items: center; @@ -37,11 +44,17 @@ .connected-badge { color: #4ade80; - font-size: 1.2rem; + font-size: 0.85rem; + font-weight: 600; +} + +.connected-badge.phantom { + color: #ab9ff2; } .address { font-weight: 500; + font-size: 0.9rem; } /* Main Content */ @@ -140,6 +153,16 @@ box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4); } +.btn-secondary { + background: linear-gradient(135deg, #ab9ff2 0%, #7c3aed 100%); + color: white; +} + +.btn-secondary:hover:not(:disabled) { + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(171, 159, 242, 0.4); +} + .btn-large { padding: 16px 32px; font-size: 1.1rem; diff --git a/examples/browser/src/vite-env.d.ts b/examples/browser/src/vite-env.d.ts new file mode 100644 index 0000000..e91619a --- /dev/null +++ b/examples/browser/src/vite-env.d.ts @@ -0,0 +1,10 @@ +/// + +interface ImportMetaEnv { + readonly VITE_CLAWSWAP_API_URL?: string; + readonly VITE_SOLANA_RPC_URL?: string; +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +} \ No newline at end of file diff --git a/examples/node-cli/e2e/sdk-integration.ts b/examples/node-cli/e2e/sdk-integration.ts index c4d09ea..84f6c7c 100644 --- a/examples/node-cli/e2e/sdk-integration.ts +++ b/examples/node-cli/e2e/sdk-integration.ts @@ -230,8 +230,7 @@ async function testExecute(): Promise { console.log(` x402 Fee: $${response.accounting.x402Fee.amountUsd}`); console.log(` Gas Reimbursement: ${response.accounting.gasReimbursement?.amountFormatted ?? 'N/A'}`); - return response; -} +}dwa xmcfr // ─── Section 4: Status ─────────────────────────────────────────────────────── diff --git a/package.json b/package.json index 7292f5d..f24acfa 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "dev": "pnpm -r dev", "example:node": "pnpm --filter @clawswap/example-node-cli dev", "example:browser": "pnpm --filter @clawswap/example-browser dev", + "example:browser-wagmi": "pnpm --filter @clawswap/example-browser-wagmi dev", "examples:install": "pnpm --filter './examples/**' install", "examples:build": "pnpm --filter './examples/**' build" }, diff --git a/packages/sdk/src/utils/http.ts b/packages/sdk/src/utils/http.ts index 1428be7..9c2dedf 100644 --- a/packages/sdk/src/utils/http.ts +++ b/packages/sdk/src/utils/http.ts @@ -12,7 +12,7 @@ export class HttpClient { constructor(config: ClawSwapConfig) { this.baseUrl = config.baseUrl || 'https://api.clawswap.dev'; - this.fetch = config.fetch || globalThis.fetch; + this.fetch = config.fetch || globalThis.fetch.bind(globalThis); this.timeout = config.timeout || 30000; this.headers = { 'Content-Type': 'application/json', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3f67f50..637d0a8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,6 +41,64 @@ importers: '@clawswap/sdk': specifier: workspace:* version: link:../../packages/sdk + '@solana/kit': + specifier: ^5.1.0 + version: 5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@solana/web3.js': + specifier: ^1.95.0 + version: 1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@x402/core': + specifier: ^2.3.0 + version: 2.3.1 + '@x402/evm': + specifier: ^2.3.0 + version: 2.3.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@x402/fetch': + specifier: ^2.3.0 + version: 2.3.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@x402/svm': + specifier: ^2.3.0 + version: 2.3.0(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10) + react: + specifier: ^18.2.0 + version: 18.3.1 + react-dom: + specifier: ^18.2.0 + version: 18.3.1(react@18.3.1) + viem: + specifier: ^2.0.0 + version: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + devDependencies: + '@types/react': + specifier: ^18.2.0 + version: 18.3.28 + '@types/react-dom': + specifier: ^18.2.0 + version: 18.3.7(@types/react@18.3.28) + '@vitejs/plugin-react': + specifier: ^4.2.1 + version: 4.7.0(vite@5.4.21(@types/node@22.7.5)) + typescript: + specifier: ^5.3.3 + version: 5.9.3 + vite: + specifier: ^5.0.0 + version: 5.4.21(@types/node@22.7.5) + + examples/browser-wagmi: + dependencies: + '@clawswap/sdk': + specifier: workspace:* + version: link:../../packages/sdk + '@solana/kit': + specifier: ^5.1.0 + version: 5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@solana/web3.js': + specifier: ^1.95.0 + version: 1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@tanstack/react-query': + specifier: ^5.0.0 + version: 5.90.21(react@18.3.1) '@x402/core': specifier: ^2.3.0 version: 2.3.1 @@ -50,6 +108,12 @@ importers: '@x402/fetch': specifier: ^2.3.0 version: 2.3.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@x402/svm': + specifier: ^2.3.0 + version: 2.3.0(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10) + connectkit: + specifier: ^1.8.0 + version: 1.9.1(@babel/core@7.29.0)(@tanstack/react-query@5.90.21(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6)) react: specifier: ^18.2.0 version: 18.3.1 @@ -58,7 +122,10 @@ importers: version: 18.3.1(react@18.3.1) viem: specifier: ^2.0.0 - version: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + wagmi: + specifier: ^2.0.0 + version: 2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) devDependencies: '@types/react': specifier: ^18.2.0 @@ -89,7 +156,7 @@ importers: version: 6.0.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) '@solana/web3-compat': specifier: ^0.0.21 - version: 0.0.21(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.2.0(react@18.3.1))(utf-8-validate@5.0.10) + version: 0.0.21(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10) '@solana/web3.js': specifier: ^1.95.0 version: 1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) @@ -104,7 +171,7 @@ importers: version: 2.3.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) '@x402/svm': specifier: ^2.3.0 - version: 2.3.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10) + version: 2.3.0(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10) bs58: specifier: ^6.0.0 version: 6.0.0 @@ -119,7 +186,7 @@ importers: version: 16.6.1 viem: specifier: ^2.0.0 - version: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + version: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) devDependencies: tsup: specifier: ^8.0.2 @@ -174,6 +241,10 @@ packages: resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.28.6': resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} engines: {node: '>=6.9.0'} @@ -217,6 +288,12 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/plugin-syntax-jsx@7.28.6': + resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-react-jsx-self@7.27.1': resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} engines: {node: '>=6.9.0'} @@ -245,6 +322,42 @@ packages: resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} + '@base-org/account@2.4.0': + resolution: {integrity: sha512-A4Umpi8B9/pqR78D1Yoze4xHyQaujioVRqqO3d6xuDFw9VRtjg6tK3bPlwE0aW+nVH/ntllCpPa2PbI8Rnjcug==} + + '@coinbase/cdp-sdk@1.44.1': + resolution: {integrity: sha512-O7sikX7gTZdF4xy9b0xAMPOKWk8z6E7an4EGVBukPdfChooBL15Zt6B8Wn5th/LC1V1nIf3J/tlTTQCJLkKZ6A==} + + '@coinbase/wallet-sdk@3.9.3': + resolution: {integrity: sha512-N/A2DRIf0Y3PHc1XAMvbBUu4zisna6qAdqABMZwBMNEfWrXpAwx16pZGkYCLGE+Rvv1edbcB2LYDRnACNcmCiw==} + + '@coinbase/wallet-sdk@4.3.6': + resolution: {integrity: sha512-4q8BNG1ViL4mSAAvPAtpwlOs1gpC+67eQtgIwNvT3xyeyFFd+guwkc8bcX5rTmQhXpqnhzC4f0obACbP9CqMSA==} + + '@ecies/ciphers@0.2.5': + resolution: {integrity: sha512-GalEZH4JgOMHYYcYmVqnFirFsjZHeoGMDt9IxEnM9F7GRUUyUksJ7Ou53L83WHJq3RWKD3AcBpo0iQh0oMpf8A==} + engines: {bun: '>=1', deno: '>=2', node: '>=16'} + peerDependencies: + '@noble/ciphers': ^1.0.0 + + '@emotion/is-prop-valid@0.8.8': + resolution: {integrity: sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==} + + '@emotion/is-prop-valid@1.4.0': + resolution: {integrity: sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==} + + '@emotion/memoize@0.7.4': + resolution: {integrity: sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==} + + '@emotion/memoize@0.9.0': + resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==} + + '@emotion/stylis@0.8.5': + resolution: {integrity: sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==} + + '@emotion/unitless@0.7.5': + resolution: {integrity: sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==} + '@esbuild/aix-ppc64@0.21.5': resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} @@ -557,6 +670,27 @@ packages: resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@ethereumjs/common@3.2.0': + resolution: {integrity: sha512-pksvzI0VyLgmuEF2FA/JR/4/y6hcPq8OUail3/AvycBaW1d5VSauOZzqGvJ3RTmR4MU35lWE8KseKOsEhrFRBA==} + + '@ethereumjs/rlp@4.0.1': + resolution: {integrity: sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==} + engines: {node: '>=14'} + hasBin: true + + '@ethereumjs/tx@4.2.0': + resolution: {integrity: sha512-1nc6VO4jtFd172BbSnTnDQVr9IYBFl1y4xPzZdtkrkKIncBCkdbgfdRV+MiTkJYAtTxvV12GRZLqBFT1PNK6Yw==} + engines: {node: '>=14'} + + '@ethereumjs/util@8.1.0': + resolution: {integrity: sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==} + engines: {node: '>=14'} + + '@gemini-wallet/core@0.3.2': + resolution: {integrity: sha512-Z4aHi3ECFf5oWYWM3F1rW83GJfB9OvhBYPTmb5q+VyK3uvzvS48lwo+jwh2eOoCRWEuT/crpb9Vwp2QaS5JqgQ==} + peerDependencies: + viem: '>=2.0.0' + '@humanwhocodes/config-array@0.13.0': resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} engines: {node: '>=10.10.0'} @@ -590,10 +724,129 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@lit-labs/ssr-dom-shim@1.5.1': + resolution: {integrity: sha512-Aou5UdlSpr5whQe8AA/bZG0jMj96CoJIWbGfZ91qieWu5AWUMKw8VR/pAkQkJYvBNhmCcWnZlyyk5oze8JIqYA==} + + '@lit/reactive-element@2.1.2': + resolution: {integrity: sha512-pbCDiVMnne1lYUIaYNN5wrwQXDtHaYtg7YEFPeW+hws6U47WeFvISGUWekPGKWOP1ygrs0ef0o1VJMk1exos5A==} + + '@metamask/eth-json-rpc-provider@1.0.1': + resolution: {integrity: sha512-whiUMPlAOrVGmX8aKYVPvlKyG4CpQXiNNyt74vE1xb5sPvmx5oA7B/kOi/JdBvhGQq97U1/AVdXEdk2zkP8qyA==} + engines: {node: '>=14.0.0'} + + '@metamask/json-rpc-engine@7.3.3': + resolution: {integrity: sha512-dwZPq8wx9yV3IX2caLi9q9xZBw2XeIoYqdyihDDDpuHVCEiqadJLwqM3zy+uwf6F1QYQ65A8aOMQg1Uw7LMLNg==} + engines: {node: '>=16.0.0'} + + '@metamask/json-rpc-engine@8.0.2': + resolution: {integrity: sha512-IoQPmql8q7ABLruW7i4EYVHWUbF74yrp63bRuXV5Zf9BQwcn5H9Ww1eLtROYvI1bUXwOiHZ6qT5CWTrDc/t/AA==} + engines: {node: '>=16.0.0'} + + '@metamask/json-rpc-middleware-stream@7.0.2': + resolution: {integrity: sha512-yUdzsJK04Ev98Ck4D7lmRNQ8FPioXYhEUZOMS01LXW8qTvPGiRVXmVltj2p4wrLkh0vW7u6nv0mNl5xzC5Qmfg==} + engines: {node: '>=16.0.0'} + + '@metamask/object-multiplex@2.1.0': + resolution: {integrity: sha512-4vKIiv0DQxljcXwfpnbsXcfa5glMj5Zg9mqn4xpIWqkv6uJ2ma5/GtUfLFSxhlxnR8asRMv8dDmWya1Tc1sDFA==} + engines: {node: ^16.20 || ^18.16 || >=20} + + '@metamask/onboarding@1.0.1': + resolution: {integrity: sha512-FqHhAsCI+Vacx2qa5mAFcWNSrTcVGMNjzxVgaX8ECSny/BJ9/vgXP9V7WF/8vb9DltPeQkxr+Fnfmm6GHfmdTQ==} + + '@metamask/providers@16.1.0': + resolution: {integrity: sha512-znVCvux30+3SaUwcUGaSf+pUckzT5ukPRpcBmy+muBLC0yaWnBcvDqGfcsw6CBIenUdFrVoAFa8B6jsuCY/a+g==} + engines: {node: ^18.18 || >=20} + + '@metamask/rpc-errors@6.4.0': + 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==} + + '@metamask/safe-event-emitter@3.1.2': + resolution: {integrity: sha512-5yb2gMI1BDm0JybZezeoX/3XhPDOtTbcFvpTXM9kxsoZjPZFh4XciqRbpD6N86HYZqWDhEaKUDuOyR0sQHEjMA==} + engines: {node: '>=12.0.0'} + + '@metamask/sdk-analytics@0.0.5': + resolution: {integrity: sha512-fDah+keS1RjSUlC8GmYXvx6Y26s3Ax1U9hGpWb6GSY5SAdmTSIqp2CvYy6yW0WgLhnYhW+6xERuD0eVqV63QIQ==} + + '@metamask/sdk-communication-layer@0.33.1': + resolution: {integrity: sha512-0bI9hkysxcfbZ/lk0T2+aKVo1j0ynQVTuB3sJ5ssPWlz+Z3VwveCkP1O7EVu1tsVVCb0YV5WxK9zmURu2FIiaA==} + peerDependencies: + cross-fetch: ^4.0.0 + eciesjs: '*' + eventemitter2: ^6.4.9 + readable-stream: ^3.6.2 + socket.io-client: ^4.5.1 + + '@metamask/sdk-install-modal-web@0.32.1': + resolution: {integrity: sha512-MGmAo6qSjf1tuYXhCu2EZLftq+DSt5Z7fsIKr2P+lDgdTPWgLfZB1tJKzNcwKKOdf6q9Qmmxn7lJuI/gq5LrKw==} + + '@metamask/sdk@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.10.0': + resolution: {integrity: sha512-+bWmTOANx1MbBW6RFM8Se4ZoigFYGXiuIrkhjj4XnG5Aez8uWaTSZ76yn9srKKClv+PoEVoAuVtcUOogFEMUNA==} + engines: {node: ^18.18 || ^20.14 || >=22} + + '@metamask/utils@5.0.2': + resolution: {integrity: sha512-yfmE79bRQtnMzarnKfX7AEJBwFTxvTyw3nBQlu/5rmGXrjAeAMltoGxO62TFurxrQAFMNa/fEjIHNvungZp0+g==} + engines: {node: '>=14.0.0'} + + '@metamask/utils@8.5.0': + resolution: {integrity: sha512-I6bkduevXb72TIM9q2LRO63JSsF9EXduh3sBr9oybNX2hNNpr/j1tEjXrsG0Uabm4MJ1xkGAQEMwifvKZIkyxQ==} + engines: {node: '>=16.0.0'} + + '@metamask/utils@9.3.0': + resolution: {integrity: sha512-w8CVbdkDrVXFJbfBSlDfafDR6BAkpDmv1bC1UJVCoVny5tW2RKAdn9i68Xf7asYT4TnUhl/hN4zfUiKQq9II4g==} + engines: {node: '>=16.0.0'} + + '@motionone/animation@10.18.0': + resolution: {integrity: sha512-9z2p5GFGCm0gBsZbi8rVMOAJCtw1WqBTIPw3ozk06gDvZInBPIsQcHgYogEJ4yuHJ+akuW8g1SEIOpTOvYs8hw==} + + '@motionone/dom@10.12.0': + resolution: {integrity: sha512-UdPTtLMAktHiqV0atOczNYyDd/d8Cf5fFsd1tua03PqTwwCe/6lwhLSQ8a7TbnQ5SN0gm44N1slBfj+ORIhrqw==} + + '@motionone/easing@10.18.0': + resolution: {integrity: sha512-VcjByo7XpdLS4o9T8t99JtgxkdMcNWD3yHU/n6CLEz3bkmKDRZyYQ/wmSf6daum8ZXqfUAgFeCZSpJZIMxaCzg==} + + '@motionone/generators@10.18.0': + resolution: {integrity: sha512-+qfkC2DtkDj4tHPu+AFKVfR/C30O1vYdvsGYaR13W/1cczPrrcjdvYCj0VLFuRMN+lP1xvpNZHCRNM4fBzn1jg==} + + '@motionone/types@10.17.1': + resolution: {integrity: sha512-KaC4kgiODDz8hswCrS0btrVrzyU2CSQKO7Ps90ibBVSQmjkrt2teqta6/sOG59v7+dPnKMAg13jyqtMKV2yJ7A==} + + '@motionone/utils@10.18.0': + resolution: {integrity: sha512-3XVF7sgyTSI2KWvTf6uLlBJ5iAgRgmvp3bpuOiQJvInd4nZ19ET8lX5unn30SlmRH7hXbBbH+Gxd0m0klJ3Xtw==} + + '@noble/ciphers@1.2.1': + resolution: {integrity: sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA==} + engines: {node: ^14.21.3 || >=16} + '@noble/ciphers@1.3.0': resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} engines: {node: ^14.21.3 || >=16} + '@noble/curves@1.4.2': + resolution: {integrity: sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==} + + '@noble/curves@1.8.0': + resolution: {integrity: sha512-j84kjAbzEnQHaSIhRPUmB3/eVXu2k3dKPl2LOrR8fSOIL+89U+7lV117EWHtq/GHM3ReGHM46iRBdZfpc4HRUQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.8.1': + 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} @@ -602,6 +855,18 @@ packages: 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'} + + '@noble/hashes@1.7.0': + resolution: {integrity: sha512-HXydb0DgzTpDPwbVeDGCG1gIu7X6+AuU6Zl6av/E/KG8LMsvPntvq+w17CHRpKBmN6Ybdrt1eP3k4cj8DJa78w==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.7.1': + resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==} + engines: {node: ^14.21.3 || >=16} + '@noble/hashes@1.8.0': resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} engines: {node: ^14.21.3 || >=16} @@ -618,6 +883,39 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@paulmillr/qr@0.2.1': + resolution: {integrity: sha512-IHnV6A+zxU7XwmKFinmYjUcwlyK9+xkG3/s9KcQhI9BjQKycrJ1JRO+FbNYPwZiPKW3je/DR0k7w8/gLa5eaxQ==} + deprecated: 'The package is now available as "qr": npm install qr' + + '@reown/appkit-common@1.7.8': + resolution: {integrity: sha512-ridIhc/x6JOp7KbDdwGKY4zwf8/iK8EYBl+HtWrruutSLwZyVi5P8WaZa+8iajL6LcDcDF7LoyLwMTym7SRuwQ==} + + '@reown/appkit-controllers@1.7.8': + resolution: {integrity: sha512-IdXlJlivrlj6m63VsGLsjtPHHsTWvKGVzWIP1fXZHVqmK+rZCBDjCi9j267Rb9/nYRGHWBtlFQhO8dK35WfeDA==} + + '@reown/appkit-pay@1.7.8': + resolution: {integrity: sha512-OSGQ+QJkXx0FEEjlpQqIhT8zGJKOoHzVnyy/0QFrl3WrQTjCzg0L6+i91Ad5Iy1zb6V5JjqtfIFpRVRWN4M3pw==} + + '@reown/appkit-polyfills@1.7.8': + resolution: {integrity: sha512-W/kq786dcHHAuJ3IV2prRLEgD/2iOey4ueMHf1sIFjhhCGMynMkhsOhQMUH0tzodPqUgAC494z4bpIDYjwWXaA==} + + '@reown/appkit-scaffold-ui@1.7.8': + resolution: {integrity: sha512-RCeHhAwOrIgcvHwYlNWMcIDibdI91waaoEYBGw71inE0kDB8uZbE7tE6DAXJmDkvl0qPh+DqlC4QbJLF1FVYdQ==} + + '@reown/appkit-ui@1.7.8': + resolution: {integrity: sha512-1hjCKjf6FLMFzrulhl0Y9Vb9Fu4royE+SXCPSWh4VhZhWqlzUFc7kutnZKx8XZFVQH4pbBvY62SpRC93gqoHow==} + + '@reown/appkit-utils@1.7.8': + resolution: {integrity: sha512-8X7UvmE8GiaoitCwNoB86pttHgQtzy4ryHZM9kQpvjQ0ULpiER44t1qpVLXNM4X35O0v18W0Dk60DnYRMH2WRw==} + peerDependencies: + valtio: 1.13.2 + + '@reown/appkit-wallet@1.7.8': + resolution: {integrity: sha512-kspz32EwHIOT/eg/ZQbFPxgXq0B/olDOj3YMu7gvLEFz4xyOFd/wgzxxAXkp5LbG4Cp++s/elh79rVNmVFdB9A==} + + '@reown/appkit@1.7.8': + resolution: {integrity: sha512-51kTleozhA618T1UvMghkhKfaPcc9JlKwLJ5uV+riHyvSoWPKPRIa5A6M1Wano5puNyW0s3fwywhyqTHSilkaA==} + '@rolldown/pluginutils@1.0.0-beta.27': resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} @@ -746,18 +1044,46 @@ packages: cpu: [x64] os: [win32] + '@safe-global/safe-apps-provider@0.18.6': + resolution: {integrity: sha512-4LhMmjPWlIO8TTDC2AwLk44XKXaK6hfBTWyljDm0HQ6TWlOEijVWNrt2s3OCVMSxlXAcEzYfqyu1daHZooTC2Q==} + + '@safe-global/safe-apps-sdk@9.1.0': + resolution: {integrity: sha512-N5p/ulfnnA2Pi2M3YeWjULeWbjo7ei22JwU/IXnhoHzKq3pYCN6ynL9mJBOlvDVv892EgLPCWCOwQk/uBT2v0Q==} + + '@safe-global/safe-gateway-typescript-sdk@3.23.1': + resolution: {integrity: sha512-6ORQfwtEJYpalCeVO21L4XXGSdbEMfyp2hEv6cP82afKXSwvse6d3sdelgaPWUxHIsFRkWvHDdzh8IyyKHZKxw==} + engines: {node: '>=16'} + + '@scure/base@1.1.9': + resolution: {integrity: sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==} + '@scure/base@1.2.6': resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} + '@scure/bip32@1.4.0': + resolution: {integrity: sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==} + + '@scure/bip32@1.6.2': + resolution: {integrity: sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==} + '@scure/bip32@1.7.0': resolution: {integrity: sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==} + '@scure/bip39@1.3.0': + resolution: {integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==} + + '@scure/bip39@1.5.4': + resolution: {integrity: sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==} + '@scure/bip39@1.6.0': resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} '@sinclair/typebox@0.27.10': resolution: {integrity: sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==} + '@socket.io/component-emitter@3.1.2': + resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} + '@solana-program/address-lookup-table@0.10.0': resolution: {integrity: sha512-lcp+IYwoFBODhg8vXsh5vpxweLxpSKqjAu8P1LyqQxgk2yqwYmJGA79YKa+lZvsQjP/c0rzIZYWIGxFMMes2zA==} peerDependencies: @@ -1357,6 +1683,14 @@ packages: '@swc/helpers@0.5.18': resolution: {integrity: sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==} + '@tanstack/query-core@5.90.20': + resolution: {integrity: sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==} + + '@tanstack/react-query@5.90.21': + resolution: {integrity: sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg==} + peerDependencies: + react: ^18 || ^19 + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -1372,9 +1706,18 @@ packages: '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/lodash@4.17.23': + resolution: {integrity: sha512-RDvF6wTulMPjrNdCoYRC8gNR880JNGT8uB+REUpC2Ns4pRqQJhGz90wh7rgdXDPpCczF3VGktDuFGVnz8zP7HA==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} @@ -1395,6 +1738,9 @@ packages: '@types/react@18.3.28': resolution: {integrity: sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==} + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/uuid@8.3.4': resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==} @@ -1486,6 +1832,28 @@ packages: '@vitest/utils@1.6.1': resolution: {integrity: sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g==} + '@wagmi/connectors@6.2.0': + resolution: {integrity: sha512-2NfkbqhNWdjfibb4abRMrn7u6rPjEGolMfApXss6HCDVt9AW2oVC6k8Q5FouzpJezElxLJSagWz9FW1zaRlanA==} + peerDependencies: + '@wagmi/core': 2.22.1 + typescript: '>=5.0.4' + viem: 2.x + peerDependenciesMeta: + typescript: + optional: true + + '@wagmi/core@2.22.1': + resolution: {integrity: sha512-cG/xwQWsBEcKgRTkQVhH29cbpbs/TdcUJVFXCyri3ZknxhMyGv0YEjTcrNpRgt2SaswL1KrvslSNYKKo+5YEAg==} + peerDependencies: + '@tanstack/query-core': '>=5.0.0' + typescript: '>=5.0.4' + viem: 2.x + peerDependenciesMeta: + '@tanstack/query-core': + optional: true + typescript: + optional: true + '@wallet-standard/app@1.1.0': resolution: {integrity: sha512-3CijvrO9utx598kjr45hTbbeeykQrQfKmSnxeWOgU25TOEpvcipD/bYDQWIqUv1Oc6KK4YStokSMu/FBNecGUQ==} engines: {node: '>=16'} @@ -1503,6 +1871,99 @@ packages: resolution: {integrity: sha512-hiEivWNztx73s+7iLxsuD1sOJ28xtRix58W7Xnz4XzzA/pF0+aicnWgjOdA10doVDEDZdUuZCIIqG96SFNlDUg==} engines: {node: '>=16'} + '@walletconnect/core@2.21.0': + resolution: {integrity: sha512-o6R7Ua4myxR8aRUAJ1z3gT9nM+jd2B2mfamu6arzy1Cc6vi10fIwFWb6vg3bC8xJ6o9H3n/cN5TOW3aA9Y1XVw==} + engines: {node: '>=18'} + + '@walletconnect/core@2.21.1': + resolution: {integrity: sha512-Tp4MHJYcdWD846PH//2r+Mu4wz1/ZU/fr9av1UWFiaYQ2t2TPLDiZxjLw54AAEpMqlEHemwCgiRiAmjR1NDdTQ==} + engines: {node: '>=18'} + + '@walletconnect/environment@1.0.1': + resolution: {integrity: sha512-T426LLZtHj8e8rYnKfzsw1aG6+M0BT1ZxayMdv/p8yM0MU+eJDISqNY3/bccxRr4LrF9csq02Rhqt08Ibl0VRg==} + + '@walletconnect/ethereum-provider@2.21.1': + resolution: {integrity: sha512-SSlIG6QEVxClgl1s0LMk4xr2wg4eT3Zn/Hb81IocyqNSGfXpjtawWxKxiC5/9Z95f1INyBD6MctJbL/R1oBwIw==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' + + '@walletconnect/events@1.0.1': + resolution: {integrity: sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ==} + + '@walletconnect/heartbeat@1.2.2': + resolution: {integrity: sha512-uASiRmC5MwhuRuf05vq4AT48Pq8RMi876zV8rr8cV969uTOzWdB/k+Lj5yI2PBtB1bGQisGen7MM1GcZlQTBXw==} + + '@walletconnect/jsonrpc-http-connection@1.0.8': + resolution: {integrity: sha512-+B7cRuaxijLeFDJUq5hAzNyef3e3tBDIxyaCNmFtjwnod5AGis3RToNqzFU33vpVcxFhofkpE7Cx+5MYejbMGw==} + + '@walletconnect/jsonrpc-provider@1.0.14': + resolution: {integrity: sha512-rtsNY1XqHvWj0EtITNeuf8PHMvlCLiS3EjQL+WOkxEOA4KPxsohFnBDeyPYiNm4ZvkQdLnece36opYidmtbmow==} + + '@walletconnect/jsonrpc-types@1.0.4': + resolution: {integrity: sha512-P6679fG/M+wuWg9TY8mh6xFSdYnFyFjwFelxyISxMDrlbXokorEVXYOxiqEbrU3x1BmBoCAJJ+vtEaEoMlpCBQ==} + + '@walletconnect/jsonrpc-utils@1.0.8': + resolution: {integrity: sha512-vdeb03bD8VzJUL6ZtzRYsFMq1eZQcM3EAzT0a3st59dyLfJ0wq+tKMpmGH7HlB7waD858UWgfIcudbPFsbzVdw==} + + '@walletconnect/jsonrpc-ws-connection@1.0.16': + resolution: {integrity: sha512-G81JmsMqh5nJheE1mPst1W0WfVv0SG3N7JggwLLGnI7iuDZJq8cRJvQwLGKHn5H1WTW7DEPCo00zz5w62AbL3Q==} + + '@walletconnect/keyvaluestorage@1.1.1': + resolution: {integrity: sha512-V7ZQq2+mSxAq7MrRqDxanTzu2RcElfK1PfNYiaVnJgJ7Q7G7hTVwF8voIBx92qsRyGHZihrwNPHuZd1aKkd0rA==} + peerDependencies: + '@react-native-async-storage/async-storage': 1.x + peerDependenciesMeta: + '@react-native-async-storage/async-storage': + optional: true + + '@walletconnect/logger@2.1.2': + resolution: {integrity: sha512-aAb28I3S6pYXZHQm5ESB+V6rDqIYfsnHaQyzFbwUUBFY4H0OXx/YtTl8lvhUNhMMfb9UxbwEBS253TlXUYJWSw==} + + '@walletconnect/relay-api@1.0.11': + resolution: {integrity: sha512-tLPErkze/HmC9aCmdZOhtVmYZq1wKfWTJtygQHoWtgg722Jd4homo54Cs4ak2RUFUZIGO2RsOpIcWipaua5D5Q==} + + '@walletconnect/relay-auth@1.1.0': + resolution: {integrity: sha512-qFw+a9uRz26jRCDgL7Q5TA9qYIgcNY8jpJzI1zAWNZ8i7mQjaijRnWFKsCHAU9CyGjvt6RKrRXyFtFOpWTVmCQ==} + + '@walletconnect/safe-json@1.0.2': + resolution: {integrity: sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA==} + + '@walletconnect/sign-client@2.21.0': + resolution: {integrity: sha512-z7h+PeLa5Au2R591d/8ZlziE0stJvdzP9jNFzFolf2RG/OiXulgFKum8PrIyXy+Rg2q95U9nRVUF9fWcn78yBA==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' + + '@walletconnect/sign-client@2.21.1': + resolution: {integrity: sha512-QaXzmPsMnKGV6tc4UcdnQVNOz4zyXgarvdIQibJ4L3EmLat73r5ZVl4c0cCOcoaV7rgM9Wbphgu5E/7jNcd3Zg==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' + + '@walletconnect/time@1.0.2': + resolution: {integrity: sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g==} + + '@walletconnect/types@2.21.0': + resolution: {integrity: sha512-ll+9upzqt95ZBWcfkOszXZkfnpbJJ2CmxMfGgE5GmhdxxxCcO5bGhXkI+x8OpiS555RJ/v/sXJYMSOLkmu4fFw==} + + '@walletconnect/types@2.21.1': + resolution: {integrity: sha512-UeefNadqP6IyfwWC1Yi7ux+ljbP2R66PLfDrDm8izmvlPmYlqRerJWJvYO4t0Vvr9wrG4Ko7E0c4M7FaPKT/sQ==} + + '@walletconnect/universal-provider@2.21.0': + resolution: {integrity: sha512-mtUQvewt+X0VBQay/xOJBvxsB3Xsm1lTwFjZ6WUwSOTR1X+FNb71hSApnV5kbsdDIpYPXeQUbGt2se1n5E5UBg==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' + + '@walletconnect/universal-provider@2.21.1': + resolution: {integrity: sha512-Wjx9G8gUHVMnYfxtasC9poGm8QMiPCpXpbbLFT+iPoQskDDly8BwueWnqKs4Mx2SdIAWAwuXeZ5ojk5qQOxJJg==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' + + '@walletconnect/utils@2.21.0': + resolution: {integrity: sha512-zfHLiUoBrQ8rP57HTPXW7rQMnYxYI4gT9yTACxVW6LhIFROTF6/ytm5SKNoIvi4a5nX5dfXG4D9XwQUCu8Ilig==} + + '@walletconnect/utils@2.21.1': + resolution: {integrity: sha512-VPZvTcrNQCkbGOjFRbC24mm/pzbRMUq2DSQoiHlhh0X1U7ZhuIrzVtAoKsrzu6rqjz0EEtGxCr3K1TGRqDG4NA==} + + '@walletconnect/window-getters@1.0.1': + resolution: {integrity: sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q==} + + '@walletconnect/window-metadata@1.0.1': + resolution: {integrity: sha512-9koTqyGrM2cqFRW517BPY/iEtUDx2r1+Pwwu5m7sJ7ka79wi3EyqhqcICk/yDmv6jAS1rjKgTKXlEhanYjijcA==} + '@x402/core@2.3.1': resolution: {integrity: sha512-CWvsf09tslISoVOzQ2TIoBLBP+bUycPsYmmRVe3EV5X2FtD7eXXpiPsiXLEVtWP7zhqLNP/5OIATsA2hSVLSfw==} @@ -1515,6 +1976,28 @@ packages: '@x402/svm@2.3.0': resolution: {integrity: sha512-Lh02bBBwv9fHSTId8Iqj+SGl9zjSYCrUHaJ0VsrN/GKBcFJwXoDNXgqc7qJGKbkdriBnvAHMxtFR1snpAaBm+w==} + abitype@1.0.6: + resolution: {integrity: sha512-MMSqYh4+C/aVqI2RQaWqbvI4Kxo5cQV40WQ4QFtDnNzCkqChm8MuENhElmynZlO0qUy/ObkEUaXtKqYnx1Kp3A==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abitype@1.0.8: + resolution: {integrity: sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + abitype@1.2.3: resolution: {integrity: sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==} peerDependencies: @@ -1562,6 +2045,10 @@ packages: any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -1572,6 +2059,33 @@ packages: assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + async-mutex@0.2.6: + resolution: {integrity: sha512-Hs4R+4SPgamu6rSGW8C7cV9gaWUKEHykfzCCvIRuaVv636Ju10ZdeUbvb4TBEW0INuq2DHZqXbK4Nd3yG4RaRw==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axios-retry@4.5.0: + resolution: {integrity: sha512-aR99oXhpEDGo0UuAlYcn2iGRds30k366Zfa05XWScR9QaQD4JYiP3/1Qt1u7YlefUOK+cn0CcwoL1oefavQUlQ==} + peerDependencies: + axios: 0.x || 1.x + + axios@1.13.5: + resolution: {integrity: sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==} + + babel-plugin-styled-components@2.1.4: + resolution: {integrity: sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==} + peerDependencies: + styled-components: '>= 2' + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -1588,12 +2102,18 @@ packages: resolution: {integrity: sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==} hasBin: true + big.js@6.2.2: + resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} + bn.js@5.2.2: resolution: {integrity: sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==} borsh@0.7.0: resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} + bowser@2.14.1: + resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==} + brace-expansion@1.1.12: resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} @@ -1632,10 +2152,29 @@ packages: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + camelize@1.0.1: + resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} + caniuse-lite@1.0.30001769: resolution: {integrity: sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==} @@ -1651,6 +2190,9 @@ packages: resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + charenc@0.0.2: + resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} + check-error@1.0.3: resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} @@ -1658,6 +2200,17 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + + cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + + clsx@1.2.1: + resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} + engines: {node: '>=6'} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -1665,6 +2218,10 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + commander@11.1.0: resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} engines: {node: '>=16'} @@ -1694,6 +2251,16 @@ packages: confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + connectkit@1.9.1: + resolution: {integrity: sha512-ac9Ki3+HdS3l5NCa6H86y7R+0PqwJ8yzsBQVtWk4/jkFo+JJioetO43A/Q0O7VtxLbfuLLfwDGZ09taePLNzfQ==} + engines: {node: '>=12.4'} + peerDependencies: + '@tanstack/react-query': '>=5.0.0' + react: 17.x || 18.x + react-dom: 17.x || 18.x + viem: 2.x + wagmi: 2.x + consola@3.4.2: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} @@ -1701,15 +2268,52 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie-es@1.2.2: + resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + cross-fetch@3.2.0: + resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} + + cross-fetch@4.1.0: + resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + crossws@0.3.5: + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + + crypt@0.0.2: + resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} + + css-color-keywords@1.0.0: + resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==} + engines: {node: '>=4'} + + css-to-react-native@3.2.0: + resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==} + csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + date-fns@2.30.0: + resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} + engines: {node: '>=0.11'} + + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -1717,21 +2321,63 @@ packages: supports-color: optional: true - deep-eql@4.1.4: - resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + + deep-eql@4.1.4: + resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} engines: {node: '>=6'} deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + delay@5.0.0: resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} engines: {node: '>=10'} + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + derive-valtio@0.1.0: + resolution: {integrity: sha512-OCg2UsLbXK7GmmpzMXhYkdO64vhJ1ROUUGaTFyHjVwEdMEcTTRj7W1TxLbSBxdY8QLBPCcp66MTyaSy0RpO17A==} + peerDependencies: + valtio: '*' + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + detect-browser@5.3.0: + resolution: {integrity: sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==} + diff-sequences@29.6.3: resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dijkstrajs@1.0.3: + resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} + dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -1744,9 +2390,55 @@ packages: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + duplexify@4.1.3: + resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} + + eciesjs@0.4.17: + resolution: {integrity: sha512-TOOURki4G7sD1wDCjj7NfLaXZZ49dFOeEb5y39IXpb8p0hRzVvfvzZHOi5JcT+PpyAbi/Y+lxPb8eTag2WYH8w==} + engines: {bun: '>=1', deno: '>=2', node: '>=16'} + electron-to-chromium@1.5.286: resolution: {integrity: sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==} + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + encode-utf8@1.0.3: + resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + + engine.io-client@6.6.4: + resolution: {integrity: sha512-+kjUJnZGwzewFDw951CDWcwj35vMNf2fcj7xQWOctq1F2i1jkDdVvdFG9kM/BEChymCH36KgjnW0NsL58JYRxw==} + + engine.io-parser@5.2.3: + resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} + engines: {node: '>=10.0.0'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-toolkit@1.33.0: + resolution: {integrity: sha512-X13Q/ZSc+vsO1q600bvNK4bxgXMkHcf//RxCmYDaRY5DAcT+eoXjY5hoAPGMdRnWQjvyLEcyauG3b6hz76LNqg==} + es6-promise@4.2.8: resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} @@ -1808,20 +2500,65 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + eth-block-tracker@7.1.0: + resolution: {integrity: sha512-8YdplnuE1IK4xfqpf4iU7oBxnOYAc35934o083G8ao+8WM8QQtt/mVlAY6yIAdY1eMeLqg4Z//PZjJGmWGPMRg==} + engines: {node: '>=14.0.0'} + + eth-json-rpc-filters@6.0.1: + resolution: {integrity: sha512-ITJTvqoCw6OVMLs7pI8f4gG92n/St6x80ACtHodeS+IXmO0w+t1T5OOzfSt7KLSMLRkVUoexV7tztLgDxg+iig==} + engines: {node: '>=14.0.0'} + + eth-query@2.1.2: + resolution: {integrity: sha512-srES0ZcvwkR/wd5OQBRA1bIJMww1skfGS0s8wlwK3/oNP4+wnds60krvu5R1QbpRQjMmpG5OMIWro5s7gvDPsA==} + + eth-rpc-errors@4.0.3: + resolution: {integrity: sha512-Z3ymjopaoft7JDoxZcEb3pwdGh7yiYMhOwm2doUt6ASXlMavpNlK6Cre0+IMl2VSGyEU9rkiperQhp5iRxn5Pg==} + + ethereum-cryptography@2.2.1: + resolution: {integrity: sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==} + + eventemitter2@6.4.9: + resolution: {integrity: sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==} + eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} eventemitter3@5.0.4: resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + execa@8.0.1: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} + extension-port-stream@3.0.0: + resolution: {integrity: sha512-an2S5quJMiy5bnZKEf6AkfH/7r8CzHvhchU40gxN+OM6HPhe7Z9T1FUychcf2M9PpPOO0Hf7BAEfJkw2TDIBDw==} + engines: {node: '>=12.0.0'} + eyes@0.1.8: resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} engines: {node: '> 0.1.90'} + family@0.1.6: + resolution: {integrity: sha512-ulHRThfhz+glfmVfSPcU16N1hZ/uj0Y1D79vl0PeJ3yFfgXlkiBbVwXRJhDQuP8oizxBCl16KT2PrMleiYwrPw==} + peerDependencies: + react: 17.x || 18.x || 19.x + react-dom: 17.x || 18.x || 19.x + viem: 2.x + wagmi: 2.x + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + viem: + optional: true + wagmi: + optional: true + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -1835,6 +2572,13 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + engines: {node: '>=6'} + + fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + fast-stable-stringify@1.0.0: resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} @@ -1861,6 +2605,14 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + filter-obj@1.1.0: + resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==} + engines: {node: '>=0.10.0'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -1875,6 +2627,32 @@ packages: flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} + + framer-motion@6.5.1: + resolution: {integrity: sha512-o1BGqqposwi7cgDrtg0dNONhkmPsUFDaLcKXigzuTFC5x58mE8iyTazxSudFzmT6MEyJKfjjU8ItoMe3W+3fiw==} + peerDependencies: + react: '>=16.8 || ^17.0.0 || ^18.0.0' + react-dom: '>=16.8 || ^17.0.0 || ^18.0.0' + + framesync@6.0.1: + resolution: {integrity: sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA==} + fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -1883,13 +2661,32 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + 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'} + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + get-func-name@2.0.2: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + get-stream@8.0.1: resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} engines: {node: '>=16'} @@ -1917,13 +2714,49 @@ packages: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + h3@1.15.5: + resolution: {integrity: sha512-xEyq3rSl+dhGX2Lm0+eFQIAzlDN6Fs0EcC4f7BNUmzaRX/PTzeuM+Tr2lHB8FoXggsQIeXLj8EDVgs5ywxyxmg==} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hey-listen@1.0.8: + resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==} + + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + + hono@4.12.0: + resolution: {integrity: sha512-NekXntS5M94pUfiVZ8oXXK/kkri+5WpX2/Ik+LVsl+uvw+soj4roXIsPqO+XsWrAw20mOzaXOZf3Q7PfB9A/IA==} + engines: {node: '>=16.9.0'} + human-signals@5.0.0: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} @@ -1931,6 +2764,12 @@ packages: humanize-ms@1.2.1: resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + idb-keyval@6.2.1: + resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==} + + idb-keyval@6.2.2: + resolution: {integrity: sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -1953,10 +2792,32 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + + is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} + engines: {node: '>= 0.4'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -1969,10 +2830,32 @@ packages: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-retry-allowed@2.2.0: + resolution: {integrity: sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==} + engines: {node: '>=10'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + is-stream@3.0.0: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -1981,6 +2864,11 @@ packages: peerDependencies: ws: '*' + isows@1.0.6: + resolution: {integrity: sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==} + peerDependencies: + ws: '*' + isows@1.0.7: resolution: {integrity: sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==} peerDependencies: @@ -1991,6 +2879,9 @@ packages: engines: {node: '>=8'} hasBin: true + jose@6.1.3: + resolution: {integrity: sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==} + joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} @@ -2013,6 +2904,13 @@ packages: json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-rpc-engine@6.1.0: + resolution: {integrity: sha512-NEdLrtrq1jUZyfjkr9OCz9EzCNhnRyWtt1PAnvnhwy6e8XETS0Dtc+ZNCO2gvuAoKsIn2+vCSowXTYE4CkgnAQ==} + engines: {node: '>=10.0.0'} + + json-rpc-random-id@1.0.1: + resolution: {integrity: sha512-RJ9YYNCkhVDBuP4zN5BBtYAzEl03yq/jIIsyif0JY9qyJuQQZNeDK7anAPKKlyEtLSj2s8h6hNh2F8zO5q7ScA==} + json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -2027,9 +2925,16 @@ packages: engines: {node: '>=6'} hasBin: true + keccak@3.0.4: + resolution: {integrity: sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==} + engines: {node: '>=10.0.0'} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + keyvaluestorage-interface@1.0.0: + resolution: {integrity: sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g==} + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -2041,6 +2946,15 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + lit-element@4.2.2: + resolution: {integrity: sha512-aFKhNToWxoyhkNDmWZwEva2SlQia+jfG0fjIWV//YeTaWrVnOxD89dPKfigCUspXFmjzOEUQpOkejH5Ly6sG0w==} + + lit-html@3.3.2: + resolution: {integrity: sha512-Qy9hU88zcmaxBXcc10ZpdK7cOLXvXpRoBxERdtqV9QOrfpMZZ6pSYP91LhpPtap3sFMUiL7Tw2RImbe0Al2/kw==} + + lit@3.3.0: + resolution: {integrity: sha512-DGVsqsOIHBww2DqnuZzW7QsuCdahp50ojuDaBPC7jUDRpYoH0z7kHBBYZewRzer75FwtrkmkKk7iOAwSaWdBmw==} + load-tsconfig@0.2.5: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2049,6 +2963,10 @@ packages: resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} engines: {node: '>=14'} + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -2056,6 +2974,9 @@ packages: lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + lodash@4.17.23: + resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} + loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -2063,12 +2984,23 @@ packages: loupe@2.3.7: resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + lru-cache@11.2.6: + resolution: {integrity: sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + md5@2.3.0: + resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==} + merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -2076,10 +3008,21 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + micro-ftch@0.3.1: + resolution: {integrity: sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==} + micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + mimic-fn@4.0.0: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} @@ -2091,12 +3034,26 @@ packages: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} + mipd@0.0.7: + resolution: {integrity: sha512-aAPZPNDQ3uMTdKbuO2YmAw2TxLHO0moa4YKAyETM/DTj5FloZo+a+8tU+iv4GmW+sOxKLSRwcSFuczk+Cpt6fg==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + mlly@1.8.0: resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + multiformats@9.9.0: + resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} + mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} @@ -2108,6 +3065,12 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + node-addon-api@2.0.2: + resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==} + + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -2121,17 +3084,33 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true + node-mock-http@1.0.4: + resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} + node-releases@2.0.27: resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + npm-run-path@5.3.0: resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + obj-multiplex@1.0.0: + resolution: {integrity: sha512-0GNJAOsHoBHeNTvl5Vt6IWnpUEcc3uSRxzBri7EDyIcMgYvnY2JL2qdeV5zTMjWQX5OHcD5amcW2HFfDh0gjIA==} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} + ofetch@1.5.1: + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} + + on-exit-leak-free@0.2.0: + resolution: {integrity: sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -2139,6 +3118,12 @@ packages: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} + 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'} @@ -2151,6 +3136,34 @@ packages: typescript: optional: true + ox@0.6.7: + resolution: {integrity: sha512-17Gk/eFsFRAZ80p5eKqv89a57uXjd3NgIf1CaXojATPBuujVc/fQSVhBeAU9JCRB+k7J50WQAyWTxK19T9GgbA==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + ox@0.6.9: + resolution: {integrity: sha512-wi5ShvzE4eOcTwQVsIPdFr+8ycyX+5le/96iAJutaZAvCes1J0+RvpEPg5QDPDiaR0XQQAvZVl7AwqQcINuUug==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + ox@0.9.17: + resolution: {integrity: sha512-rKAnhzhRU3Xh3hiko+i1ZxywZ55eWQzeS/Q4HRKLx2PqfHOolisZHErSsJVipGlmQKHW5qwOED/GighEw9dbLg==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -2159,10 +3172,18 @@ packages: resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} engines: {node: '>=18'} + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -2207,6 +3228,24 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + + pify@5.0.0: + resolution: {integrity: sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==} + engines: {node: '>=10'} + + pino-abstract-transport@0.5.0: + resolution: {integrity: sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==} + + pino-std-serializers@4.0.0: + resolution: {integrity: sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==} + + pino@7.11.0: + resolution: {integrity: sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==} + hasBin: true + pirates@4.0.7: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} @@ -2214,6 +3253,53 @@ packages: pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + pngjs@5.0.0: + resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} + engines: {node: '>=10.13.0'} + + pony-cause@2.1.11: + resolution: {integrity: sha512-M7LhCsdNbNgiLYiP4WjsfLUuFmCfnjdF6jKe2R9NKl4WFN+HZPGHJZ9lnLP7f9ZnKe3U9nuWD0szirmj+migUg==} + engines: {node: '>=12.0.0'} + + popmotion@11.0.3: + resolution: {integrity: sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA==} + + porto@0.2.35: + resolution: {integrity: sha512-gu9FfjjvvYBgQXUHWTp6n3wkTxVtEcqFotM7i3GEZeoQbvLGbssAicCz6hFZ8+xggrJWwi/RLmbwNra50SMmUQ==} + hasBin: true + peerDependencies: + '@tanstack/react-query': '>=5.59.0' + '@wagmi/core': '>=2.16.3' + expo-auth-session: '>=7.0.8' + expo-crypto: '>=15.0.7' + expo-web-browser: '>=15.0.8' + react: '>=18' + react-native: '>=0.81.4' + typescript: '>=5.4.0' + viem: '>=2.37.0' + wagmi: '>=2.0.0' + peerDependenciesMeta: + '@tanstack/react-query': + optional: true + expo-auth-session: + optional: true + expo-crypto: + optional: true + expo-web-browser: + optional: true + react: + optional: true + react-native: + optional: true + typescript: + optional: true + wagmi: + optional: true + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + postcss-load-config@6.0.1: resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} engines: {node: '>= 18'} @@ -2232,10 +3318,19 @@ packages: yaml: optional: true + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} + preact@10.24.2: + resolution: {integrity: sha512-1cSoF0aCC8uaARATfrlz4VCBqE8LwZwRfLgkxJOQwAlQt6ayTmi0D9OF7nXid1POI5SZidFuG9CnlXbDfLqY/Q==} + + preact@10.28.4: + resolution: {integrity: sha512-uKFfOHWuSNpRFVTnljsCluEFq57OKT+0QdOiQo8XWnQ/pSvg7OpX5eNOejELXJMWy+BwM2nobz0FkvzmnpCNsQ==} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -2249,18 +3344,56 @@ packages: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process-warning@1.0.0: + resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} + + proxy-compare@2.6.0: + resolution: {integrity: sha512-8xuCeM3l8yqdmbPoYeLbrAXCBWu19XEYc5/F28f5qOaoAIMyfmBUkl5axiK+x9olUvRlcekvnm98AP9RDngOIw==} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + pump@3.0.3: + resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + qrcode@1.5.3: + resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==} + engines: {node: '>=10.13.0'} + hasBin: true + + qrcode@1.5.4: + resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==} + engines: {node: '>=10.13.0'} + hasBin: true + + query-string@7.1.3: + resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==} + engines: {node: '>=6'} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + react-dom@18.3.1: resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} peerDependencies: react: ^18.3.1 + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} @@ -2268,14 +3401,54 @@ packages: resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} engines: {node: '>=0.10.0'} + react-transition-state@1.1.5: + resolution: {integrity: sha512-ITY2mZqc2dWG2eitJkYNdcSFW8aKeOlkL2A/vowRrLL8GH3J6Re/SpD/BLvQzrVOTqjsP0b5S9N10vgNNzwMUQ==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + react-use-measure@2.1.7: + resolution: {integrity: sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==} + peerDependencies: + react: '>=16.13' + react-dom: '>=16.13' + peerDependenciesMeta: + react-dom: + optional: true + react@18.3.1: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + readdirp@4.1.2: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + readdirp@5.0.0: + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} + engines: {node: '>= 20.19.0'} + + real-require@0.1.0: + resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} + engines: {node: '>= 12.13.0'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + + resize-observer-polyfill@1.5.1: + resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -2307,9 +3480,20 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + scheduler@0.23.2: resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} @@ -2322,6 +3506,21 @@ packages: engines: {node: '>=10'} hasBin: true + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + sha.js@2.4.12: + resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} + engines: {node: '>= 0.10'} + hasBin: true + + shallowequal@1.1.0: + resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2341,6 +3540,17 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + socket.io-client@4.8.3: + resolution: {integrity: sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g==} + engines: {node: '>=10.0.0'} + + socket.io-parser@4.2.5: + resolution: {integrity: sha512-bPMmpy/5WWKHea5Y/jYAP6k74A+hvmRCQaJuJB6I/ML5JZq/KfNieUVo/3Mh7SAqn7TyFdIo6wqYHInG1MU1bQ==} + engines: {node: '>=10.0.0'} + + sonic-boom@2.8.0: + resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -2349,6 +3559,14 @@ packages: resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} engines: {node: '>= 12'} + split-on-first@1.1.0: + resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} + engines: {node: '>=6'} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} @@ -2361,7 +3579,24 @@ packages: stream-json@1.9.1: resolution: {integrity: sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==} - strip-ansi@6.0.1: + stream-shift@1.0.3: + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + + strict-uri-encode@2.0.0: + resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} + engines: {node: '>=4'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -2376,15 +3611,34 @@ packages: strip-literal@2.1.1: resolution: {integrity: sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==} + style-value-types@5.0.0: + resolution: {integrity: sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA==} + + styled-components@5.3.11: + resolution: {integrity: sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==} + engines: {node: '>=10'} + peerDependencies: + react: '>= 16.8.0' + react-dom: '>= 16.8.0' + react-is: '>= 16.8.0' + sucrase@3.35.1: resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} engines: {node: '>=16 || 14 >=14.17'} hasBin: true + superstruct@1.0.4: + resolution: {integrity: sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ==} + engines: {node: '>=14.0.0'} + superstruct@2.0.2: resolution: {integrity: sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==} engines: {node: '>=14.0.0'} + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -2402,6 +3656,9 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + thread-stream@0.15.2: + resolution: {integrity: sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -2420,6 +3677,10 @@ packages: resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} engines: {node: '>=14.0.0'} + to-buffer@1.2.2: + resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} + engines: {node: '>= 0.4'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -2440,6 +3701,9 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -2479,6 +3743,10 @@ packages: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + typescript@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} @@ -2487,6 +3755,12 @@ packages: ufo@1.6.3: resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} + uint8arrays@3.1.0: + resolution: {integrity: sha512-ei5rfKtoRO8OyOIor2Rz5fhzjThwIHJZ3uyDPnDHTXbP0aMQ1RN/6AI5B5d9dBxJOU+BvOAk7ZQ1xphsX8Lrog==} + + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} @@ -2496,6 +3770,68 @@ packages: undici-types@7.21.0: resolution: {integrity: sha512-w9IMgQrz4O0YN1LtB7K5P63vhlIOvC7opSmouCJ+ZywlPAlO9gIkJ+otk6LvGpAs2wg4econaCz3TvQ9xPoyuQ==} + unstorage@1.17.4: + resolution: {integrity: sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw==} + peerDependencies: + '@azure/app-configuration': ^1.8.0 + '@azure/cosmos': ^4.2.0 + '@azure/data-tables': ^13.3.0 + '@azure/identity': ^4.6.0 + '@azure/keyvault-secrets': ^4.9.0 + '@azure/storage-blob': ^12.26.0 + '@capacitor/preferences': ^6 || ^7 || ^8 + '@deno/kv': '>=0.9.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.34.3 + '@vercel/blob': '>=0.27.1' + '@vercel/functions': ^2.2.12 || ^3.0.0 + '@vercel/kv': ^1 || ^2 || ^3 + aws4fetch: ^1.0.20 + db0: '>=0.2.1' + idb-keyval: ^6.2.1 + ioredis: ^5.4.2 + uploadthing: ^7.4.4 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@deno/kv': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/blob': + optional: true + '@vercel/functions': + optional: true + '@vercel/kv': + optional: true + aws4fetch: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + uploadthing: + optional: true + update-browserslist-db@1.2.3: resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true @@ -2510,14 +3846,49 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 + use-sync-external-store@1.4.0: + resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + utf-8-validate@5.0.10: resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} engines: {node: '>=6.14.2'} + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + + valtio@1.13.2: + resolution: {integrity: sha512-Qik0o+DSy741TmkqmRfjq+0xpZBXi/Y6+fXZLn0xNF1z/waFMbE3rkivv5Zcf9RrMUp6zswf2J7sbh2KBlba5A==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=16.8' + react: '>=16.8' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + + viem@2.23.2: + resolution: {integrity: sha512-NVmW/E0c5crMOtbEAqMF0e3NmvQykFXhLOc/CkLIXOlzHSA6KXVz3CYVmaKqBF8/xtjsjHAGjdJN3Ru1kFJLaA==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + viem@2.45.3: resolution: {integrity: sha512-axOD7rIbGiDHHA1MHKmpqqTz3CMCw7YpE/FVypddQMXL5i364VkNZh9JeEJH17NO484LaZUOMueo35IXyL76Mw==} peerDependencies: @@ -2587,12 +3958,33 @@ packages: jsdom: optional: true + wagmi@2.19.5: + resolution: {integrity: sha512-RQUfKMv6U+EcSNNGiPbdkDtJwtuFxZWLmvDiQmjjBgkuPulUwDJsKhi7gjynzJdsx2yDqhHCXkKsbbfbIsHfcQ==} + peerDependencies: + '@tanstack/react-query': '>=5.0.0' + react: '>=18' + typescript: '>=5.0.4' + viem: 2.x + peerDependenciesMeta: + typescript: + optional: true + + webextension-polyfill@0.10.0: + resolution: {integrity: sha512-c5s35LgVa5tFaHhrZDnr3FpQpjj1BB+RXhLTYUxGqBVN460HkbM8TBtEqdXWbpTKfzwCcjAZVF7zXCYSKtcp9g==} + webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + + which-typed-array@1.1.20: + resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} + engines: {node: '>= 0.4'} + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -2607,6 +3999,10 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -2622,6 +4018,18 @@ packages: utf-8-validate: optional: true + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + ws@8.18.3: resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} engines: {node: '>=10.0.0'} @@ -2646,9 +4054,28 @@ packages: utf-8-validate: optional: true + xmlhttprequest-ssl@2.1.2: + resolution: {integrity: sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==} + engines: {node: '>=0.4.0'} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + + yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -2657,9 +4084,33 @@ packages: resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} engines: {node: '>=12.20'} + zod@3.22.4: + resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + + zustand@5.0.0: + resolution: {integrity: sha512-LE+VcmbartOPM+auOjCCLQOsQ05zUTp8RkgwRzefUk+2jISdMMFnxvyTjA4YNWr5ZGXYbVsEMZosttuxUBkojQ==} + 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.11: resolution: {integrity: sha512-fdZY+dk7zn/vbWNCYmzZULHRrss0jx5pPFiOuMZ/5HJN6Yv3u+1Wswy/4MpZEkEGhtNH+pwxZB8OKgUBPzYAGg==} engines: {node: '>=12.20.0'} @@ -2678,6 +4129,24 @@ packages: use-sync-external-store: optional: true + zustand@5.0.3: + resolution: {integrity: sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=18.0.0' + immer: '>=9.0.6' + react: '>=18.0.0' + use-sync-external-store: '>=1.2.0' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + snapshots: '@adraffy/ens-normalize@1.11.1': {} @@ -2699,11 +4168,11 @@ snapshots: '@babel/helpers': 7.28.6 '@babel/parser': 7.29.0 '@babel/template': 7.28.6 - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.0(supports-color@5.5.0) '@babel/types': 7.29.0 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@5.5.0) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -2718,6 +4187,10 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.29.0 + '@babel/helper-compilation-targets@7.28.6': dependencies: '@babel/compat-data': 7.29.0 @@ -2728,9 +4201,9 @@ snapshots: '@babel/helper-globals@7.28.0': {} - '@babel/helper-module-imports@7.28.6': + '@babel/helper-module-imports@7.28.6(supports-color@5.5.0)': dependencies: - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.0(supports-color@5.5.0) '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color @@ -2738,9 +4211,9 @@ snapshots: '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-module-imports': 7.28.6 + '@babel/helper-module-imports': 7.28.6(supports-color@5.5.0) '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.0(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -2761,6 +4234,11 @@ snapshots: dependencies: '@babel/types': 7.29.0 + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 @@ -2779,7 +4257,7 @@ snapshots: '@babel/parser': 7.29.0 '@babel/types': 7.29.0 - '@babel/traverse@7.29.0': + '@babel/traverse@7.29.0(supports-color@5.5.0)': dependencies: '@babel/code-frame': 7.29.0 '@babel/generator': 7.29.1 @@ -2787,7 +4265,7 @@ snapshots: '@babel/parser': 7.29.0 '@babel/template': 7.28.6 '@babel/types': 7.29.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -2796,6 +4274,108 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 + '@base-org/account@2.4.0(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@4.3.6)': + dependencies: + '@coinbase/cdp-sdk': 1.44.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@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.3.6) + preact: 10.24.2 + viem: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + zustand: 5.0.3(@types/react@18.3.28)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) + transitivePeerDependencies: + - '@types/react' + - bufferutil + - debug + - encoding + - fastestsmallesttextencoderdecoder + - immer + - react + - typescript + - use-sync-external-store + - utf-8-validate + - zod + + '@coinbase/cdp-sdk@1.44.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)': + dependencies: + '@solana-program/system': 0.10.0(@solana/kit@5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)) + '@solana-program/token': 0.9.0(@solana/kit@5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)) + '@solana/kit': 5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + abitype: 1.0.6(typescript@5.9.3)(zod@3.25.76) + axios: 1.13.5 + axios-retry: 4.5.0(axios@1.13.5) + jose: 6.1.3 + md5: 2.3.0 + uncrypto: 0.1.3 + viem: 2.45.3(bufferutil@4.1.0)(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 + + '@coinbase/wallet-sdk@3.9.3': + dependencies: + bn.js: 5.2.2 + buffer: 6.0.3 + clsx: 1.2.1 + eth-block-tracker: 7.1.0 + eth-json-rpc-filters: 6.0.1 + eventemitter3: 5.0.4 + keccak: 3.0.4 + preact: 10.28.4 + sha.js: 2.4.12 + transitivePeerDependencies: + - supports-color + + '@coinbase/wallet-sdk@4.3.6(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@4.3.6)': + 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.3.6) + preact: 10.24.2 + viem: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + zustand: 5.0.3(@types/react@18.3.28)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) + transitivePeerDependencies: + - '@types/react' + - bufferutil + - immer + - react + - typescript + - use-sync-external-store + - utf-8-validate + - zod + + '@ecies/ciphers@0.2.5(@noble/ciphers@1.3.0)': + dependencies: + '@noble/ciphers': 1.3.0 + + '@emotion/is-prop-valid@0.8.8': + dependencies: + '@emotion/memoize': 0.7.4 + optional: true + + '@emotion/is-prop-valid@1.4.0': + dependencies: + '@emotion/memoize': 0.9.0 + + '@emotion/memoize@0.7.4': + optional: true + + '@emotion/memoize@0.9.0': {} + + '@emotion/stylis@0.8.5': {} + + '@emotion/unitless@0.7.5': {} + '@esbuild/aix-ppc64@0.21.5': optional: true @@ -2953,7 +4533,7 @@ snapshots: '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 - debug: 4.4.3 + debug: 4.4.3(supports-color@5.5.0) espree: 9.6.1 globals: 13.24.0 ignore: 5.3.2 @@ -2966,10 +4546,38 @@ snapshots: '@eslint/js@8.57.1': {} + '@ethereumjs/common@3.2.0': + dependencies: + '@ethereumjs/util': 8.1.0 + crc-32: 1.2.2 + + '@ethereumjs/rlp@4.0.1': {} + + '@ethereumjs/tx@4.2.0': + dependencies: + '@ethereumjs/common': 3.2.0 + '@ethereumjs/rlp': 4.0.1 + '@ethereumjs/util': 8.1.0 + ethereum-cryptography: 2.2.1 + + '@ethereumjs/util@8.1.0': + dependencies: + '@ethereumjs/rlp': 4.0.1 + ethereum-cryptography: 2.2.1 + micro-ftch: 0.3.1 + + '@gemini-wallet/core@0.3.2(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))': + dependencies: + '@metamask/rpc-errors': 7.0.2 + eventemitter3: 5.0.1 + viem: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + transitivePeerDependencies: + - supports-color + '@humanwhocodes/config-array@0.13.0': dependencies: '@humanwhocodes/object-schema': 2.0.3 - debug: 4.4.3 + debug: 4.4.3(supports-color@5.5.0) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -3001,49 +4609,558 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@noble/ciphers@1.3.0': {} + '@lit-labs/ssr-dom-shim@1.5.1': {} - '@noble/curves@1.9.1': + '@lit/reactive-element@2.1.2': dependencies: - '@noble/hashes': 1.8.0 + '@lit-labs/ssr-dom-shim': 1.5.1 - '@noble/curves@1.9.7': + '@metamask/eth-json-rpc-provider@1.0.1': dependencies: - '@noble/hashes': 1.8.0 + '@metamask/json-rpc-engine': 7.3.3 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 5.0.2 + transitivePeerDependencies: + - supports-color - '@noble/hashes@1.8.0': {} + '@metamask/json-rpc-engine@7.3.3': + dependencies: + '@metamask/rpc-errors': 6.4.0 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 8.5.0 + transitivePeerDependencies: + - supports-color - '@nodelib/fs.scandir@2.1.5': + '@metamask/json-rpc-engine@8.0.2': dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 + '@metamask/rpc-errors': 6.4.0 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 8.5.0 + transitivePeerDependencies: + - supports-color - '@nodelib/fs.stat@2.0.5': {} + '@metamask/json-rpc-middleware-stream@7.0.2': + dependencies: + '@metamask/json-rpc-engine': 8.0.2 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 8.5.0 + readable-stream: 3.6.2 + transitivePeerDependencies: + - supports-color - '@nodelib/fs.walk@1.2.8': + '@metamask/object-multiplex@2.1.0': dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.20.1 + once: 1.4.0 + readable-stream: 3.6.2 - '@rolldown/pluginutils@1.0.0-beta.27': {} + '@metamask/onboarding@1.0.1': + dependencies: + bowser: 2.14.1 - '@rollup/rollup-android-arm-eabi@4.57.1': - optional: true + '@metamask/providers@16.1.0': + dependencies: + '@metamask/json-rpc-engine': 8.0.2 + '@metamask/json-rpc-middleware-stream': 7.0.2 + '@metamask/object-multiplex': 2.1.0 + '@metamask/rpc-errors': 6.4.0 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 8.5.0 + detect-browser: 5.3.0 + extension-port-stream: 3.0.0 + fast-deep-equal: 3.1.3 + is-stream: 2.0.1 + readable-stream: 3.6.2 + webextension-polyfill: 0.10.0 + transitivePeerDependencies: + - supports-color - '@rollup/rollup-android-arm64@4.57.1': - optional: true + '@metamask/rpc-errors@6.4.0': + dependencies: + '@metamask/utils': 9.3.0 + fast-safe-stringify: 2.1.1 + transitivePeerDependencies: + - supports-color - '@rollup/rollup-darwin-arm64@4.57.1': - optional: true + '@metamask/rpc-errors@7.0.2': + dependencies: + '@metamask/utils': 11.10.0 + fast-safe-stringify: 2.1.1 + transitivePeerDependencies: + - supports-color - '@rollup/rollup-darwin-x64@4.57.1': - optional: true + '@metamask/safe-event-emitter@2.0.0': {} - '@rollup/rollup-freebsd-arm64@4.57.1': - optional: true + '@metamask/safe-event-emitter@3.1.2': {} - '@rollup/rollup-freebsd-x64@4.57.1': - optional: true + '@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.17)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.3(bufferutil@4.1.0)(utf-8-validate@5.0.10))': + dependencies: + '@metamask/sdk-analytics': 0.0.5 + bufferutil: 4.1.0 + cross-fetch: 4.1.0 + date-fns: 2.30.0 + debug: 4.3.4 + eciesjs: 0.4.17 + eventemitter2: 6.4.9 + readable-stream: 3.6.2 + socket.io-client: 4.8.3(bufferutil@4.1.0)(utf-8-validate@5.0.10) + utf-8-validate: 5.0.10 + uuid: 8.3.2 + transitivePeerDependencies: + - supports-color + + '@metamask/sdk-install-modal-web@0.32.1': + dependencies: + '@paulmillr/qr': 0.2.1 + + '@metamask/sdk@0.33.1(bufferutil@4.1.0)(utf-8-validate@5.0.10)': + dependencies: + '@babel/runtime': 7.28.6 + '@metamask/onboarding': 1.0.1 + '@metamask/providers': 16.1.0 + '@metamask/sdk-analytics': 0.0.5 + '@metamask/sdk-communication-layer': 0.33.1(cross-fetch@4.1.0)(eciesjs@0.4.17)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.3(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + '@metamask/sdk-install-modal-web': 0.32.1 + '@paulmillr/qr': 0.2.1 + bowser: 2.14.1 + cross-fetch: 4.1.0 + debug: 4.3.4 + eciesjs: 0.4.17 + eth-rpc-errors: 4.0.3 + eventemitter2: 6.4.9 + obj-multiplex: 1.0.0 + pump: 3.0.3 + readable-stream: 3.6.2 + socket.io-client: 4.8.3(bufferutil@4.1.0)(utf-8-validate@5.0.10) + tslib: 2.8.1 + util: 0.12.5 + uuid: 8.3.2 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + '@metamask/superstruct@3.2.1': {} + + '@metamask/utils@11.10.0': + dependencies: + '@ethereumjs/tx': 4.2.0 + '@metamask/superstruct': 3.2.1 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@types/debug': 4.1.12 + '@types/lodash': 4.17.23 + debug: 4.4.3(supports-color@5.5.0) + lodash: 4.17.23 + pony-cause: 2.1.11 + semver: 7.7.4 + 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.3(supports-color@5.5.0) + semver: 7.7.4 + superstruct: 1.0.4 + transitivePeerDependencies: + - supports-color + + '@metamask/utils@8.5.0': + dependencies: + '@ethereumjs/tx': 4.2.0 + '@metamask/superstruct': 3.2.1 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@types/debug': 4.1.12 + debug: 4.4.3(supports-color@5.5.0) + pony-cause: 2.1.11 + semver: 7.7.4 + uuid: 9.0.1 + transitivePeerDependencies: + - supports-color + + '@metamask/utils@9.3.0': + dependencies: + '@ethereumjs/tx': 4.2.0 + '@metamask/superstruct': 3.2.1 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@types/debug': 4.1.12 + debug: 4.4.3(supports-color@5.5.0) + pony-cause: 2.1.11 + semver: 7.7.4 + uuid: 9.0.1 + transitivePeerDependencies: + - supports-color + + '@motionone/animation@10.18.0': + dependencies: + '@motionone/easing': 10.18.0 + '@motionone/types': 10.17.1 + '@motionone/utils': 10.18.0 + tslib: 2.8.1 + + '@motionone/dom@10.12.0': + dependencies: + '@motionone/animation': 10.18.0 + '@motionone/generators': 10.18.0 + '@motionone/types': 10.17.1 + '@motionone/utils': 10.18.0 + hey-listen: 1.0.8 + tslib: 2.8.1 + + '@motionone/easing@10.18.0': + dependencies: + '@motionone/utils': 10.18.0 + tslib: 2.8.1 + + '@motionone/generators@10.18.0': + dependencies: + '@motionone/types': 10.17.1 + '@motionone/utils': 10.18.0 + tslib: 2.8.1 + + '@motionone/types@10.17.1': {} + + '@motionone/utils@10.18.0': + dependencies: + '@motionone/types': 10.17.1 + hey-listen: 1.0.8 + tslib: 2.8.1 + + '@noble/ciphers@1.2.1': {} + + '@noble/ciphers@1.3.0': {} + + '@noble/curves@1.4.2': + dependencies: + '@noble/hashes': 1.4.0 + + '@noble/curves@1.8.0': + dependencies: + '@noble/hashes': 1.7.0 + + '@noble/curves@1.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.20.1 + + '@paulmillr/qr@0.2.1': {} + + '@reown/appkit-common@1.7.8(bufferutil@4.1.0)(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.45.3(bufferutil@4.1.0)(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.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': + dependencies: + big.js: 6.2.2 + dayjs: 1.11.13 + viem: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@reown/appkit-controllers@1.7.8(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@walletconnect/universal-provider': 2.21.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + valtio: 1.13.2(@types/react@18.3.28)(react@18.3.1) + viem: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + 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@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@reown/appkit-controllers': 1.7.8(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@reown/appkit-ui': 1.7.8(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@reown/appkit-utils': 1.7.8(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.28)(react@18.3.1))(zod@4.3.6) + lit: 3.3.0 + valtio: 1.13.2(@types/react@18.3.28)(react@18.3.1) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@reown/appkit-polyfills@1.7.8': + dependencies: + buffer: 6.0.3 + + '@reown/appkit-scaffold-ui@1.7.8(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.28)(react@18.3.1))(zod@4.3.6)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@reown/appkit-controllers': 1.7.8(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@reown/appkit-ui': 1.7.8(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@reown/appkit-utils': 1.7.8(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.28)(react@18.3.1))(zod@4.3.6) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.1.0)(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-ui@1.7.8(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@reown/appkit-controllers': 1.7.8(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.1.0)(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-utils@1.7.8(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.28)(react@18.3.1))(zod@4.3.6)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@reown/appkit-controllers': 1.7.8(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@reown/appkit-polyfills': 1.7.8 + '@reown/appkit-wallet': 1.7.8(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@walletconnect/logger': 2.1.2 + '@walletconnect/universal-provider': 2.21.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + valtio: 1.13.2(@types/react@18.3.28)(react@18.3.1) + viem: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@reown/appkit-wallet@1.7.8(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-polyfills': 1.7.8 + '@walletconnect/logger': 2.1.2 + zod: 3.22.4 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + + '@reown/appkit@1.7.8(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@reown/appkit-controllers': 1.7.8(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@reown/appkit-pay': 1.7.8(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@reown/appkit-polyfills': 1.7.8 + '@reown/appkit-scaffold-ui': 1.7.8(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.28)(react@18.3.1))(zod@4.3.6) + '@reown/appkit-ui': 1.7.8(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@reown/appkit-utils': 1.7.8(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@18.3.28)(react@18.3.1))(zod@4.3.6) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@walletconnect/types': 2.21.0 + '@walletconnect/universal-provider': 2.21.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + bs58: 6.0.0 + valtio: 1.13.2(@types/react@18.3.28)(react@18.3.1) + viem: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@rolldown/pluginutils@1.0.0-beta.27': {} + + '@rollup/rollup-android-arm-eabi@4.57.1': + optional: true + + '@rollup/rollup-android-arm64@4.57.1': + optional: true + + '@rollup/rollup-darwin-arm64@4.57.1': + optional: true + + '@rollup/rollup-darwin-x64@4.57.1': + optional: true + + '@rollup/rollup-freebsd-arm64@4.57.1': + optional: true + + '@rollup/rollup-freebsd-x64@4.57.1': + optional: true '@rollup/rollup-linux-arm-gnueabihf@4.57.1': optional: true @@ -3102,14 +5219,60 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.57.1': optional: true + '@safe-global/safe-apps-provider@0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': + dependencies: + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + events: 3.3.0 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': + dependencies: + '@safe-global/safe-gateway-typescript-sdk': 3.23.1 + viem: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@safe-global/safe-gateway-typescript-sdk@3.23.1': {} + + '@scure/base@1.1.9': {} + '@scure/base@1.2.6': {} + '@scure/bip32@1.4.0': + dependencies: + '@noble/curves': 1.4.2 + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.9 + + '@scure/bip32@1.6.2': + dependencies: + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@scure/base': 1.2.6 + '@scure/bip32@1.7.0': dependencies: '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 + '@scure/bip39@1.3.0': + dependencies: + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.9 + + '@scure/bip39@1.5.4': + dependencies: + '@noble/hashes': 1.7.1 + '@scure/base': 1.2.6 + '@scure/bip39@1.6.0': dependencies: '@noble/hashes': 1.8.0 @@ -3117,6 +5280,8 @@ snapshots: '@sinclair/typebox@0.27.10': {} + '@socket.io/component-emitter@3.1.2': {} + '@solana-program/address-lookup-table@0.10.0(@solana/kit@5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10))': dependencies: '@solana/kit': 5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10) @@ -3133,9 +5298,10 @@ snapshots: dependencies: '@solana/kit': 5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10) - '@solana-program/token-2022@0.6.1(@solana/kit@5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10))': + '@solana-program/token-2022@0.6.1(@solana/kit@5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))': dependencies: '@solana/kit': 5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@solana/sysvars': 5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) '@solana-program/token-2022@0.7.0(@solana/kit@5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10))': dependencies: @@ -3198,7 +5364,7 @@ snapshots: dependencies: buffer: 6.0.3 - '@solana/client@1.7.0(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.2.0(react@18.3.1))(utf-8-validate@5.0.10)': + '@solana/client@1.7.0(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)': dependencies: '@solana-program/address-lookup-table': 0.10.0(@solana/kit@5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)) '@solana-program/compute-budget': 0.11.0(@solana/kit@5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)) @@ -3217,7 +5383,7 @@ snapshots: '@wallet-standard/features': 1.1.0 bs58: 6.0.0 typescript: 5.9.3 - zustand: 5.0.11(@types/react@18.3.28)(react@18.3.1)(use-sync-external-store@1.2.0(react@18.3.1)) + zustand: 5.0.11(@types/react@18.3.28)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) transitivePeerDependencies: - '@solana/sysvars' - '@types/react' @@ -3800,10 +5966,10 @@ snapshots: '@wallet-standard/base': 1.1.0 '@wallet-standard/features': 1.1.0 - '@solana/web3-compat@0.0.21(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.2.0(react@18.3.1))(utf-8-validate@5.0.10)': + '@solana/web3-compat@0.0.21(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)': dependencies: '@solana/addresses': 5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) - '@solana/client': 1.7.0(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.2.0(react@18.3.1))(utf-8-validate@5.0.10) + '@solana/client': 1.7.0(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10) '@solana/compat': 5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) '@solana/kit': 5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10) '@solana/transactions': 5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) @@ -3849,6 +6015,13 @@ snapshots: dependencies: tslib: 2.8.1 + '@tanstack/query-core@5.90.20': {} + + '@tanstack/react-query@5.90.21(react@18.3.1)': + dependencies: + '@tanstack/query-core': 5.90.20 + react: 18.3.1 + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.29.0 @@ -3874,8 +6047,16 @@ snapshots: dependencies: '@types/node': 20.19.33 + '@types/debug@4.1.12': + dependencies: + '@types/ms': 2.1.0 + '@types/estree@1.0.8': {} + '@types/lodash@4.17.23': {} + + '@types/ms@2.1.0': {} + '@types/node@12.20.55': {} '@types/node@20.19.33': @@ -3898,6 +6079,8 @@ snapshots: '@types/prop-types': 15.7.15 csstype: 3.2.3 + '@types/trusted-types@2.0.7': {} + '@types/uuid@8.3.4': {} '@types/ws@7.4.7': @@ -3932,7 +6115,7 @@ snapshots: '@typescript-eslint/types': 7.18.0 '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.9.3) '@typescript-eslint/visitor-keys': 7.18.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@5.5.0) eslint: 8.57.1 optionalDependencies: typescript: 5.9.3 @@ -3948,7 +6131,7 @@ snapshots: dependencies: '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.9.3) '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.9.3) - debug: 4.4.3 + debug: 4.4.3(supports-color@5.5.0) eslint: 8.57.1 ts-api-utils: 1.4.3(typescript@5.9.3) optionalDependencies: @@ -3962,7 +6145,7 @@ snapshots: dependencies: '@typescript-eslint/types': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@5.5.0) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.5 @@ -4032,11 +6215,79 @@ snapshots: loupe: 2.3.7 pretty-format: 29.7.0 - '@wallet-standard/app@1.1.0': - dependencies: - '@wallet-standard/base': 1.1.0 - - '@wallet-standard/base@1.1.0': {} + '@wagmi/connectors@6.2.0(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.20)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6))(zod@4.3.6)': + dependencies: + '@base-org/account': 2.4.0(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@4.3.6) + '@coinbase/wallet-sdk': 4.3.6(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@4.3.6) + '@gemini-wallet/core': 0.3.2(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)) + '@metamask/sdk': 0.33.1(bufferutil@4.1.0)(utf-8-validate@5.0.10) + '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.20)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + cbw-sdk: '@coinbase/wallet-sdk@3.9.3' + porto: 0.2.35(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.20)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)))(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6)) + viem: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + 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 + - debug + - encoding + - expo-auth-session + - expo-crypto + - expo-web-browser + - fastestsmallesttextencoderdecoder + - immer + - ioredis + - react + - react-native + - supports-color + - uploadthing + - use-sync-external-store + - utf-8-validate + - wagmi + - zod + + '@wagmi/core@2.22.1(@tanstack/query-core@5.90.20)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))': + dependencies: + eventemitter3: 5.0.1 + mipd: 0.0.7(typescript@5.9.3) + viem: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + zustand: 5.0.0(@types/react@18.3.28)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) + optionalDependencies: + '@tanstack/query-core': 5.90.20 + typescript: 5.9.3 + transitivePeerDependencies: + - '@types/react' + - immer + - 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/errors@0.1.1': dependencies: @@ -4047,6 +6298,543 @@ snapshots: dependencies: '@wallet-standard/base': 1.1.0 + '@walletconnect/core@2.21.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': + dependencies: + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.1.0)(utf-8-validate@5.0.10) + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/logger': 2.1.2 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.0 + '@walletconnect/utils': 2.21.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@walletconnect/window-getters': 1.0.1 + es-toolkit: 1.33.0 + events: 3.3.0 + uint8arrays: 3.1.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/core@2.21.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': + dependencies: + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.1.0)(utf-8-validate@5.0.10) + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/logger': 2.1.2 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.1 + '@walletconnect/utils': 2.21.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@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/environment@1.0.1': + dependencies: + tslib: 1.14.1 + + '@walletconnect/ethereum-provider@2.21.1(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': + dependencies: + '@reown/appkit': 1.7.8(@types/react@18.3.28)(bufferutil@4.1.0)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@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 + '@walletconnect/sign-client': 2.21.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@walletconnect/types': 2.21.1 + '@walletconnect/universal-provider': 2.21.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@walletconnect/utils': 2.21.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/events@1.0.1': + dependencies: + keyvaluestorage-interface: 1.0.0 + tslib: 1.14.1 + + '@walletconnect/heartbeat@1.2.2': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/time': 1.0.2 + events: 3.3.0 + + '@walletconnect/jsonrpc-http-connection@1.0.8': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + cross-fetch: 3.2.0 + events: 3.3.0 + transitivePeerDependencies: + - encoding + + '@walletconnect/jsonrpc-provider@1.0.14': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 + + '@walletconnect/jsonrpc-types@1.0.4': + dependencies: + events: 3.3.0 + keyvaluestorage-interface: 1.0.0 + + '@walletconnect/jsonrpc-utils@1.0.8': + dependencies: + '@walletconnect/environment': 1.0.1 + '@walletconnect/jsonrpc-types': 1.0.4 + tslib: 1.14.1 + + '@walletconnect/jsonrpc-ws-connection@1.0.16(bufferutil@4.1.0)(utf-8-validate@5.0.10)': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 + ws: 7.5.10(bufferutil@4.1.0)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@walletconnect/keyvaluestorage@1.1.1': + dependencies: + '@walletconnect/safe-json': 1.0.2 + idb-keyval: 6.2.2 + unstorage: 1.17.4(idb-keyval@6.2.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' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@walletconnect/logger@2.1.2': + dependencies: + '@walletconnect/safe-json': 1.0.2 + pino: 7.11.0 + + '@walletconnect/relay-api@1.0.11': + dependencies: + '@walletconnect/jsonrpc-types': 1.0.4 + + '@walletconnect/relay-auth@1.1.0': + dependencies: + '@noble/curves': 1.8.0 + '@noble/hashes': 1.7.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + uint8arrays: 3.1.0 + + '@walletconnect/safe-json@1.0.2': + dependencies: + tslib: 1.14.1 + + '@walletconnect/sign-client@2.21.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': + dependencies: + '@walletconnect/core': 2.21.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@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 + '@walletconnect/utils': 2.21.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/sign-client@2.21.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': + dependencies: + '@walletconnect/core': 2.21.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@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 + '@walletconnect/utils': 2.21.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/time@1.0.2': + dependencies: + tslib: 1.14.1 + + '@walletconnect/types@2.21.0': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/logger': 2.1.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@walletconnect/types@2.21.1': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/logger': 2.1.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@walletconnect/universal-provider@2.21.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': + 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 + '@walletconnect/logger': 2.1.2 + '@walletconnect/sign-client': 2.21.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@walletconnect/types': 2.21.0 + '@walletconnect/utils': 2.21.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + es-toolkit: 1.33.0 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/universal-provider@2.21.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': + 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 + '@walletconnect/logger': 2.1.2 + '@walletconnect/sign-client': 2.21.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@walletconnect/types': 2.21.1 + '@walletconnect/utils': 2.21.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + 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(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': + 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 + '@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 + '@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.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + 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(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': + 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 + '@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 + '@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.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + 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/window-getters@1.0.1': + dependencies: + tslib: 1.14.1 + + '@walletconnect/window-metadata@1.0.1': + dependencies: + '@walletconnect/window-getters': 1.0.1 + tslib: 1.14.1 + '@x402/core@2.3.1': dependencies: zod: 3.25.76 @@ -4071,11 +6859,11 @@ snapshots: - typescript - utf-8-validate - '@x402/svm@2.3.0(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)': + '@x402/svm@2.3.0(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)': dependencies: '@solana-program/compute-budget': 0.11.0(@solana/kit@5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)) '@solana-program/token': 0.9.0(@solana/kit@5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)) - '@solana-program/token-2022': 0.6.1(@solana/kit@5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)) + '@solana-program/token-2022': 0.6.1(@solana/kit@5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10))(@solana/sysvars@5.5.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)) '@solana/kit': 5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10) '@x402/core': 2.3.1 transitivePeerDependencies: @@ -4085,11 +6873,31 @@ snapshots: - typescript - utf-8-validate + 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@4.3.6): + optionalDependencies: + typescript: 5.9.3 + zod: 4.3.6 + + abitype@1.2.3(typescript@5.9.3)(zod@3.22.4): + optionalDependencies: + typescript: 5.9.3 + zod: 3.22.4 + abitype@1.2.3(typescript@5.9.3)(zod@3.25.76): optionalDependencies: typescript: 5.9.3 zod: 3.25.76 + abitype@1.2.3(typescript@5.9.3)(zod@4.3.6): + optionalDependencies: + typescript: 5.9.3 + zod: 4.3.6 + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: acorn: 8.15.0 @@ -4121,12 +6929,54 @@ snapshots: any-promise@1.3.0: {} + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + argparse@2.0.1: {} array-union@2.1.0: {} assertion-error@1.1.0: {} + async-mutex@0.2.6: + dependencies: + tslib: 2.8.1 + + asynckit@0.4.0: {} + + atomic-sleep@1.0.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + axios-retry@4.5.0(axios@1.13.5): + dependencies: + axios: 1.13.5 + is-retry-allowed: 2.2.0 + + axios@1.13.5: + dependencies: + follow-redirects: 1.15.11 + form-data: 4.0.5 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + babel-plugin-styled-components@2.1.4(@babel/core@7.29.0)(styled-components@5.3.11(@babel/core@7.29.0)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1))(supports-color@5.5.0): + dependencies: + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-module-imports': 7.28.6(supports-color@5.5.0) + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + lodash: 4.17.23 + picomatch: 2.3.1 + styled-components: 5.3.11(@babel/core@7.29.0)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1) + transitivePeerDependencies: + - '@babel/core' + - supports-color + balanced-match@1.0.2: {} base-x@3.0.11: @@ -4139,6 +6989,8 @@ snapshots: baseline-browser-mapping@2.9.19: {} + big.js@6.2.2: {} + bn.js@5.2.2: {} borsh@0.7.0: @@ -4147,6 +6999,8 @@ snapshots: bs58: 4.0.1 text-encoding-utf-8: 1.0.2 + bowser@2.14.1: {} + brace-expansion@1.1.12: dependencies: balanced-match: 1.0.2 @@ -4184,7 +7038,6 @@ snapshots: bufferutil@4.1.0: dependencies: node-gyp-build: 4.8.4 - optional: true bundle-require@5.1.0(esbuild@0.27.3): dependencies: @@ -4193,8 +7046,29 @@ snapshots: cac@6.7.14: {} + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + callsites@3.1.0: {} + camelcase@5.3.1: {} + + camelize@1.0.1: {} + caniuse-lite@1.0.30001769: {} chai@4.5.0: @@ -4214,6 +7088,8 @@ snapshots: chalk@5.6.2: {} + charenc@0.0.2: {} + check-error@1.0.3: dependencies: get-func-name: 2.0.2 @@ -4222,12 +7098,28 @@ snapshots: dependencies: readdirp: 4.1.2 + chokidar@5.0.0: + dependencies: + readdirp: 5.0.0 + + cliui@6.0.0: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + + clsx@1.2.1: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 color-name@1.1.4: {} + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + commander@11.1.0: {} commander@13.1.0: {} @@ -4244,21 +7136,89 @@ snapshots: confbox@0.1.8: {} + connectkit@1.9.1(@babel/core@7.29.0)(@tanstack/react-query@5.90.21(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6)): + dependencies: + '@tanstack/react-query': 5.90.21(react@18.3.1) + buffer: 6.0.3 + detect-browser: 5.3.0 + family: 0.1.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6)) + framer-motion: 6.5.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + qrcode: 1.5.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-transition-state: 1.1.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-use-measure: 2.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + resize-observer-polyfill: 1.5.1 + styled-components: 5.3.11(@babel/core@7.29.0)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1) + viem: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + wagmi: 2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) + transitivePeerDependencies: + - '@babel/core' + - react-is + consola@3.4.2: {} convert-source-map@2.0.0: {} + cookie-es@1.2.2: {} + + core-util-is@1.0.3: {} + + crc-32@1.2.2: {} + + cross-fetch@3.2.0: + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + + cross-fetch@4.1.0: + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 + crossws@0.3.5: + dependencies: + uncrypto: 0.1.3 + + crypt@0.0.2: {} + + css-color-keywords@1.0.0: {} + + css-to-react-native@3.2.0: + dependencies: + camelize: 1.0.1 + css-color-keywords: 1.0.0 + postcss-value-parser: 4.2.0 + csstype@3.2.3: {} - debug@4.4.3: + date-fns@2.30.0: + dependencies: + '@babel/runtime': 7.28.6 + + dayjs@1.11.13: {} + + debug@4.3.4: + dependencies: + ms: 2.1.2 + + debug@4.4.3(supports-color@5.5.0): dependencies: ms: 2.1.3 + optionalDependencies: + supports-color: 5.5.0 + + decamelize@1.2.0: {} + + decode-uri-component@0.2.2: {} deep-eql@4.1.4: dependencies: @@ -4266,10 +7226,30 @@ snapshots: deep-is@0.1.4: {} + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + defu@6.1.4: {} + delay@5.0.0: {} + delayed-stream@1.0.0: {} + + derive-valtio@0.1.0(valtio@1.13.2(@types/react@18.3.28)(react@18.3.1)): + dependencies: + valtio: 1.13.2(@types/react@18.3.28)(react@18.3.1) + + destr@2.0.5: {} + + detect-browser@5.3.0: {} + diff-sequences@29.6.3: {} + dijkstrajs@1.0.3: {} + dir-glob@3.0.1: dependencies: path-type: 4.0.0 @@ -4280,8 +7260,67 @@ snapshots: dotenv@16.6.1: {} + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + duplexify@4.1.3: + dependencies: + end-of-stream: 1.4.5 + inherits: 2.0.4 + readable-stream: 3.6.2 + stream-shift: 1.0.3 + + eciesjs@0.4.17: + dependencies: + '@ecies/ciphers': 0.2.5(@noble/ciphers@1.3.0) + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + electron-to-chromium@1.5.286: {} + emoji-regex@8.0.0: {} + + encode-utf8@1.0.3: {} + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + + engine.io-client@6.6.4(bufferutil@4.1.0)(utf-8-validate@5.0.10): + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.4.3(supports-color@5.5.0) + engine.io-parser: 5.2.3 + ws: 8.18.3(bufferutil@4.1.0)(utf-8-validate@5.0.10) + xmlhttprequest-ssl: 2.1.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + engine.io-parser@5.2.3: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-toolkit@1.33.0: {} + es6-promise@4.2.8: {} es6-promisify@5.0.0: @@ -4367,7 +7406,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.3 + debug: 4.4.3(supports-color@5.5.0) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -4419,10 +7458,48 @@ snapshots: esutils@2.0.3: {} + eth-block-tracker@7.1.0: + dependencies: + '@metamask/eth-json-rpc-provider': 1.0.1 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 5.0.2 + json-rpc-random-id: 1.0.1 + pify: 3.0.0 + transitivePeerDependencies: + - supports-color + + eth-json-rpc-filters@6.0.1: + dependencies: + '@metamask/safe-event-emitter': 3.1.2 + async-mutex: 0.2.6 + eth-query: 2.1.2 + json-rpc-engine: 6.1.0 + pify: 5.0.0 + + eth-query@2.1.2: + dependencies: + json-rpc-random-id: 1.0.1 + xtend: 4.0.2 + + eth-rpc-errors@4.0.3: + dependencies: + fast-safe-stringify: 2.1.1 + + ethereum-cryptography@2.2.1: + dependencies: + '@noble/curves': 1.4.2 + '@noble/hashes': 1.4.0 + '@scure/bip32': 1.4.0 + '@scure/bip39': 1.3.0 + + eventemitter2@6.4.9: {} + eventemitter3@5.0.1: {} eventemitter3@5.0.4: {} + events@3.3.0: {} + execa@8.0.1: dependencies: cross-spawn: 7.0.6 @@ -4435,8 +7512,20 @@ snapshots: signal-exit: 4.1.0 strip-final-newline: 3.0.0 + extension-port-stream@3.0.0: + dependencies: + readable-stream: 3.6.2 + webextension-polyfill: 0.10.0 + eyes@0.1.8: {} + family@0.1.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6)): + optionalDependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + viem: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + wagmi: 2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) + fast-deep-equal@3.1.3: {} fast-glob@3.3.3: @@ -4451,6 +7540,10 @@ snapshots: fast-levenshtein@2.0.6: {} + fast-redact@3.5.0: {} + + fast-safe-stringify@2.1.1: {} + fast-stable-stringify@1.0.0: {} fastestsmallesttextencoderdecoder@1.0.22: @@ -4472,6 +7565,13 @@ snapshots: dependencies: to-regex-range: 5.0.1 + filter-obj@1.1.0: {} + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + find-up@5.0.0: dependencies: locate-path: 6.0.0 @@ -4491,15 +7591,70 @@ snapshots: flatted@3.3.3: {} + follow-redirects@1.15.11: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + form-data@4.0.5: + 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 + + framer-motion@6.5.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@motionone/dom': 10.12.0 + framesync: 6.0.1 + hey-listen: 1.0.8 + popmotion: 11.0.3 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + style-value-types: 5.0.0 + tslib: 2.8.1 + optionalDependencies: + '@emotion/is-prop-valid': 0.8.8 + + framesync@6.0.1: + dependencies: + tslib: 2.8.1 + fs.realpath@1.0.0: {} fsevents@2.3.3: optional: true + function-bind@1.1.2: {} + + generator-function@2.0.1: {} + gensync@1.0.0-beta.2: {} + get-caller-file@2.0.5: {} + get-func-name@2.0.2: {} + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + get-stream@8.0.1: {} get-tsconfig@4.13.6: @@ -4536,16 +7691,58 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 + gopd@1.2.0: {} + graphemer@1.4.0: {} + h3@1.15.5: + 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.4 + radix3: 1.1.2 + ufo: 1.6.3 + uncrypto: 0.1.3 + + has-flag@3.0.0: {} + has-flag@4.0.0: {} + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hey-listen@1.0.8: {} + + hoist-non-react-statics@3.3.2: + dependencies: + react-is: 16.13.1 + + hono@4.12.0: {} + human-signals@5.0.0: {} humanize-ms@1.2.1: dependencies: ms: 2.1.3 + idb-keyval@6.2.1: {} + + idb-keyval@6.2.2: {} + ieee754@1.2.1: {} ignore@5.3.2: {} @@ -4564,8 +7761,29 @@ snapshots: inherits@2.0.4: {} + iron-webcrypto@1.2.1: {} + + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-buffer@1.1.6: {} + + is-callable@1.2.7: {} + is-extglob@2.1.1: {} + is-fullwidth-code-point@3.0.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 + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 @@ -4574,14 +7792,37 @@ snapshots: is-path-inside@3.0.3: {} + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-retry-allowed@2.2.0: {} + + is-stream@2.0.1: {} + is-stream@3.0.0: {} + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.20 + + isarray@1.0.0: {} + + isarray@2.0.5: {} + isexe@2.0.0: {} isomorphic-ws@4.0.1(ws@7.5.10(bufferutil@4.1.0)(utf-8-validate@5.0.10)): dependencies: ws: 7.5.10(bufferutil@4.1.0)(utf-8-validate@5.0.10) + isows@1.0.6(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)): + dependencies: + ws: 8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) + isows@1.0.7(ws@8.18.3): dependencies: ws: 8.18.3(bufferutil@4.1.0)(utf-8-validate@5.0.10) @@ -4604,6 +7845,8 @@ snapshots: - bufferutil - utf-8-validate + jose@6.1.3: {} + joycon@3.1.1: {} js-tokens@4.0.0: {} @@ -4618,6 +7861,13 @@ snapshots: json-buffer@3.0.1: {} + json-rpc-engine@6.1.0: + dependencies: + '@metamask/safe-event-emitter': 2.0.0 + eth-rpc-errors: 4.0.3 + + json-rpc-random-id@1.0.1: {} + json-schema-traverse@0.4.1: {} json-stable-stringify-without-jsonify@1.0.1: {} @@ -4626,10 +7876,18 @@ snapshots: json5@2.2.3: {} + keccak@3.0.4: + dependencies: + node-addon-api: 2.0.2 + node-gyp-build: 4.8.4 + readable-stream: 3.6.2 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 + keyvaluestorage-interface@1.0.0: {} + levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -4639,6 +7897,22 @@ snapshots: lines-and-columns@1.2.4: {} + lit-element@4.2.2: + dependencies: + '@lit-labs/ssr-dom-shim': 1.5.1 + '@lit/reactive-element': 2.1.2 + lit-html: 3.3.2 + + lit-html@3.3.2: + dependencies: + '@types/trusted-types': 2.0.7 + + lit@3.3.0: + dependencies: + '@lit/reactive-element': 2.1.2 + lit-element: 4.2.2 + lit-html: 3.3.2 + load-tsconfig@0.2.5: {} local-pkg@0.5.1: @@ -4646,12 +7920,18 @@ snapshots: mlly: 1.8.0 pkg-types: 1.3.1 + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + locate-path@6.0.0: dependencies: p-locate: 5.0.0 lodash.merge@4.6.2: {} + lodash@4.17.23: {} + loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 @@ -4660,6 +7940,8 @@ snapshots: dependencies: get-func-name: 2.0.2 + lru-cache@11.2.6: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -4668,15 +7950,31 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + math-intrinsics@1.1.0: {} + + md5@2.3.0: + dependencies: + charenc: 0.0.2 + crypt: 0.0.2 + is-buffer: 1.1.6 + merge-stream@2.0.0: {} merge2@1.4.1: {} + micro-ftch@0.3.1: {} + micromatch@4.0.8: dependencies: braces: 3.0.3 picomatch: 2.3.1 + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + mimic-fn@4.0.0: {} minimatch@3.1.2: @@ -4687,6 +7985,10 @@ snapshots: dependencies: brace-expansion: 2.0.2 + mipd@0.0.7(typescript@5.9.3): + optionalDependencies: + typescript: 5.9.3 + mlly@1.8.0: dependencies: acorn: 8.15.0 @@ -4694,8 +7996,12 @@ snapshots: pkg-types: 1.3.1 ufo: 1.6.3 + ms@2.1.2: {} + ms@2.1.3: {} + multiformats@9.9.0: {} + mz@2.7.0: dependencies: any-promise: 1.3.0 @@ -4706,39 +8012,139 @@ snapshots: natural-compare@1.4.0: {} + node-addon-api@2.0.2: {} + + node-fetch-native@1.6.7: {} + node-fetch@2.7.0: dependencies: whatwg-url: 5.0.0 - node-gyp-build@4.8.4: - optional: true + node-gyp-build@4.8.4: {} + + node-mock-http@1.0.4: {} node-releases@2.0.27: {} + normalize-path@3.0.0: {} + npm-run-path@5.3.0: dependencies: path-key: 4.0.0 + obj-multiplex@1.0.0: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + readable-stream: 2.3.8 + object-assign@4.1.1: {} + ofetch@1.5.1: + dependencies: + destr: 2.0.5 + node-fetch-native: 1.6.7 + ufo: 1.6.3 + + on-exit-leak-free@0.2.0: {} + once@1.4.0: dependencies: wrappy: 1.0.2 - onetime@6.0.0: + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.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 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + ox@0.12.1(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.2.3(typescript@5.9.3)(zod@3.22.4) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + + ox@0.12.1(typescript@5.9.3)(zod@3.25.76): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@5.9.3)(zod@3.25.76) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + + ox@0.12.1(typescript@5.9.3)(zod@4.3.6): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@5.9.3)(zod@4.3.6) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + + ox@0.6.7(typescript@5.9.3)(zod@4.3.6): dependencies: - mimic-fn: 4.0.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.2.3(typescript@5.9.3)(zod@4.3.6) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod - optionator@0.9.4: + ox@0.6.9(typescript@5.9.3)(zod@4.3.6): dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 + '@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.2.3(typescript@5.9.3)(zod@4.3.6) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod - ox@0.12.1(typescript@5.9.3)(zod@3.25.76): + ox@0.9.17(typescript@5.9.3)(zod@4.3.6): dependencies: '@adraffy/ens-normalize': 1.11.1 '@noble/ciphers': 1.3.0 @@ -4746,13 +8152,17 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.2.3(typescript@5.9.3)(zod@3.25.76) + abitype: 1.2.3(typescript@5.9.3)(zod@4.3.6) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - zod + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 @@ -4761,10 +8171,16 @@ snapshots: dependencies: yocto-queue: 1.2.2 + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + p-locate@5.0.0: dependencies: p-limit: 3.1.0 + p-try@2.2.0: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -4791,6 +8207,31 @@ snapshots: picomatch@4.0.3: {} + pify@3.0.0: {} + + pify@5.0.0: {} + + pino-abstract-transport@0.5.0: + dependencies: + duplexify: 4.1.3 + split2: 4.2.0 + + pino-std-serializers@4.0.0: {} + + pino@7.11.0: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 0.2.0 + pino-abstract-transport: 0.5.0 + pino-std-serializers: 4.0.0 + process-warning: 1.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.1.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 2.8.0 + thread-stream: 0.15.2 + pirates@4.0.7: {} pkg-types@1.3.1: @@ -4799,6 +8240,39 @@ snapshots: mlly: 1.8.0 pathe: 2.0.3 + pngjs@5.0.0: {} + + pony-cause@2.1.11: {} + + popmotion@11.0.3: + dependencies: + framesync: 6.0.1 + hey-listen: 1.0.8 + style-value-types: 5.0.0 + tslib: 2.8.1 + + porto@0.2.35(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.20)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)))(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6)): + dependencies: + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.20)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)) + hono: 4.12.0 + idb-keyval: 6.2.2 + mipd: 0.0.7(typescript@5.9.3) + ox: 0.9.17(typescript@5.9.3)(zod@4.3.6) + viem: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + zod: 4.3.6 + zustand: 5.0.11(@types/react@18.3.28)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) + optionalDependencies: + '@tanstack/react-query': 5.90.21(react@18.3.1) + react: 18.3.1 + typescript: 5.9.3 + wagmi: 2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) + transitivePeerDependencies: + - '@types/react' + - immer + - use-sync-external-store + + possible-typed-array-names@1.1.0: {} + postcss-load-config@6.0.1(postcss@8.5.6)(tsx@4.21.0): dependencies: lilconfig: 3.1.3 @@ -4806,12 +8280,18 @@ snapshots: postcss: 8.5.6 tsx: 4.21.0 + postcss-value-parser@4.2.0: {} + postcss@8.5.6: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 + preact@10.24.2: {} + + preact@10.28.4: {} + prelude-ls@1.2.1: {} prettier@3.8.1: {} @@ -4822,26 +8302,102 @@ snapshots: ansi-styles: 5.2.0 react-is: 18.3.1 + process-nextick-args@2.0.1: {} + + process-warning@1.0.0: {} + + proxy-compare@2.6.0: {} + + proxy-from-env@1.1.0: {} + + pump@3.0.3: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + punycode@2.3.1: {} + qrcode@1.5.3: + dependencies: + dijkstrajs: 1.0.3 + encode-utf8: 1.0.3 + pngjs: 5.0.0 + yargs: 15.4.1 + + qrcode@1.5.4: + dependencies: + dijkstrajs: 1.0.3 + pngjs: 5.0.0 + yargs: 15.4.1 + + query-string@7.1.3: + dependencies: + decode-uri-component: 0.2.2 + filter-obj: 1.1.0 + split-on-first: 1.1.0 + strict-uri-encode: 2.0.0 + queue-microtask@1.2.3: {} + quick-format-unescaped@4.0.4: {} + + radix3@1.1.2: {} + react-dom@18.3.1(react@18.3.1): dependencies: loose-envify: 1.4.0 react: 18.3.1 scheduler: 0.23.2 + react-is@16.13.1: {} + react-is@18.3.1: {} react-refresh@0.17.0: {} + react-transition-state@1.1.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + react-use-measure@2.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + react: 18.3.1 + optionalDependencies: + react-dom: 18.3.1(react@18.3.1) + react@18.3.1: dependencies: loose-envify: 1.4.0 + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + readdirp@4.1.2: {} + readdirp@5.0.0: {} + + real-require@0.1.0: {} + + require-directory@2.1.1: {} + + require-main-filename@2.0.0: {} + + resize-observer-polyfill@1.5.1: {} + resolve-from@4.0.0: {} resolve-from@5.0.0: {} @@ -4902,8 +8458,18 @@ snapshots: dependencies: queue-microtask: 1.2.3 + safe-buffer@5.1.2: {} + safe-buffer@5.2.1: {} + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + safe-stable-stringify@2.5.0: {} + scheduler@0.23.2: dependencies: loose-envify: 1.4.0 @@ -4912,6 +8478,25 @@ snapshots: semver@7.7.4: {} + set-blocking@2.0.0: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + sha.js@2.4.12: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + to-buffer: 1.2.2 + + shallowequal@1.1.0: {} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -4924,10 +8509,36 @@ snapshots: slash@3.0.0: {} + socket.io-client@4.8.3(bufferutil@4.1.0)(utf-8-validate@5.0.10): + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.4.3(supports-color@5.5.0) + engine.io-client: 6.6.4(bufferutil@4.1.0)(utf-8-validate@5.0.10) + socket.io-parser: 4.2.5 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + socket.io-parser@4.2.5: + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.4.3(supports-color@5.5.0) + transitivePeerDependencies: + - supports-color + + sonic-boom@2.8.0: + dependencies: + atomic-sleep: 1.0.0 + source-map-js@1.2.1: {} source-map@0.7.6: {} + split-on-first@1.1.0: {} + + split2@4.2.0: {} + stackback@0.0.2: {} std-env@3.10.0: {} @@ -4938,6 +8549,24 @@ snapshots: dependencies: stream-chain: 2.2.5 + stream-shift@1.0.3: {} + + strict-uri-encode@2.0.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -4950,6 +8579,29 @@ snapshots: dependencies: js-tokens: 9.0.1 + style-value-types@5.0.0: + dependencies: + hey-listen: 1.0.8 + tslib: 2.8.1 + + styled-components@5.3.11(@babel/core@7.29.0)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1): + dependencies: + '@babel/helper-module-imports': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.29.0(supports-color@5.5.0) + '@emotion/is-prop-valid': 1.4.0 + '@emotion/stylis': 0.8.5 + '@emotion/unitless': 0.7.5 + babel-plugin-styled-components: 2.1.4(@babel/core@7.29.0)(styled-components@5.3.11(@babel/core@7.29.0)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1))(supports-color@5.5.0) + css-to-react-native: 3.2.0 + hoist-non-react-statics: 3.3.2 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-is: 18.3.1 + shallowequal: 1.1.0 + supports-color: 5.5.0 + transitivePeerDependencies: + - '@babel/core' + sucrase@3.35.1: dependencies: '@jridgewell/gen-mapping': 0.3.13 @@ -4960,8 +8612,14 @@ snapshots: tinyglobby: 0.2.15 ts-interface-checker: 0.1.13 + superstruct@1.0.4: {} + superstruct@2.0.2: {} + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -4978,6 +8636,10 @@ snapshots: dependencies: any-promise: 1.3.0 + thread-stream@0.15.2: + dependencies: + real-require: 0.1.0 + tinybench@2.9.0: {} tinyexec@0.3.2: {} @@ -4991,6 +8653,12 @@ snapshots: tinyspy@2.2.1: {} + to-buffer@1.2.2: + dependencies: + isarray: 2.0.5 + safe-buffer: 5.2.1 + typed-array-buffer: 1.0.3 + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -5005,6 +8673,8 @@ snapshots: ts-interface-checker@0.1.13: {} + tslib@1.14.1: {} + tslib@2.8.1: {} tsup@8.5.1(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3): @@ -5013,7 +8683,7 @@ snapshots: cac: 6.7.14 chokidar: 4.0.3 consola: 3.4.2 - debug: 4.4.3 + debug: 4.4.3(supports-color@5.5.0) esbuild: 0.27.3 fix-dts-default-cjs-exports: 1.0.1 joycon: 3.1.1 @@ -5050,10 +8720,22 @@ snapshots: type-fest@0.20.2: {} + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + typescript@5.9.3: {} ufo@1.6.3: {} + uint8arrays@3.1.0: + dependencies: + multiformats: 9.9.0 + + uncrypto@0.1.3: {} + undici-types@6.19.8: optional: true @@ -5061,6 +8743,19 @@ snapshots: undici-types@7.21.0: {} + unstorage@1.17.4(idb-keyval@6.2.2): + dependencies: + anymatch: 3.1.3 + chokidar: 5.0.0 + destr: 2.0.5 + h3: 1.15.5 + lru-cache: 11.2.6 + node-fetch-native: 1.6.7 + ofetch: 1.5.1 + ufo: 1.6.3 + optionalDependencies: + idb-keyval: 6.2.2 + update-browserslist-db@1.2.3(browserslist@4.28.1): dependencies: browserslist: 4.28.1 @@ -5074,15 +8769,72 @@ snapshots: use-sync-external-store@1.2.0(react@18.3.1): dependencies: react: 18.3.1 - optional: true + + use-sync-external-store@1.4.0(react@18.3.1): + dependencies: + react: 18.3.1 utf-8-validate@5.0.10: dependencies: node-gyp-build: 4.8.4 - optional: true + + util-deprecate@1.0.2: {} + + util@0.12.5: + dependencies: + inherits: 2.0.4 + is-arguments: 1.2.0 + is-generator-function: 1.1.2 + is-typed-array: 1.1.15 + which-typed-array: 1.1.20 uuid@8.3.2: {} + uuid@9.0.1: {} + + valtio@1.13.2(@types/react@18.3.28)(react@18.3.1): + dependencies: + derive-valtio: 0.1.0(valtio@1.13.2(@types/react@18.3.28)(react@18.3.1)) + proxy-compare: 2.6.0 + use-sync-external-store: 1.2.0(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + react: 18.3.1 + + viem@2.23.2(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6): + 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@4.3.6) + isows: 1.0.6(ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + ox: 0.6.7(typescript@5.9.3)(zod@4.3.6) + ws: 8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.45.3(bufferutil@4.1.0)(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.2.3(typescript@5.9.3)(zod@3.22.4) + isows: 1.0.7(ws@8.18.3) + ox: 0.12.1(typescript@5.9.3)(zod@3.22.4) + ws: 8.18.3(bufferutil@4.1.0)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76): dependencies: '@noble/curves': 1.9.1 @@ -5100,10 +8852,27 @@ snapshots: - utf-8-validate - zod + viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6): + dependencies: + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@5.9.3)(zod@4.3.6) + isows: 1.0.7(ws@8.18.3) + ox: 0.12.1(typescript@5.9.3)(zod@4.3.6) + ws: 8.18.3(bufferutil@4.1.0)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + vite-node@1.6.1(@types/node@20.19.33): dependencies: cac: 6.7.14 - debug: 4.4.3 + debug: 4.4.3(supports-color@5.5.0) pathe: 1.1.2 picocolors: 1.1.1 vite: 5.4.21(@types/node@20.19.33) @@ -5145,7 +8914,7 @@ snapshots: '@vitest/utils': 1.6.1 acorn-walk: 8.3.4 chai: 4.5.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@5.5.0) execa: 8.0.1 local-pkg: 0.5.1 magic-string: 0.30.21 @@ -5170,6 +8939,53 @@ snapshots: - supports-color - terser + wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6): + dependencies: + '@tanstack/react-query': 5.90.21(react@18.3.1) + '@wagmi/connectors': 6.2.0(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.20)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(wagmi@2.19.5(@tanstack/query-core@5.90.20)(@tanstack/react-query@5.90.21(react@18.3.1))(@types/react@18.3.28)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.3.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6))(zod@4.3.6) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.20)(@types/react@18.3.28)(react@18.3.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)) + react: 18.3.1 + use-sync-external-store: 1.4.0(react@18.3.1) + viem: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + 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 + - debug + - encoding + - expo-auth-session + - expo-crypto + - expo-web-browser + - fastestsmallesttextencoderdecoder + - immer + - ioredis + - react-native + - supports-color + - uploadthing + - utf-8-validate + - zod + + webextension-polyfill@0.10.0: {} + webidl-conversions@3.0.1: {} whatwg-url@5.0.0: @@ -5177,6 +8993,18 @@ snapshots: tr46: 0.0.3 webidl-conversions: 3.0.1 + which-module@2.0.1: {} + + which-typed-array@1.1.20: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + which@2.0.2: dependencies: isexe: 2.0.0 @@ -5188,6 +9016,12 @@ snapshots: word-wrap@1.2.5: {} + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrappy@1.0.2: {} ws@7.5.10(bufferutil@4.1.0)(utf-8-validate@5.0.10): @@ -5195,6 +9029,11 @@ snapshots: bufferutil: 4.1.0 utf-8-validate: 5.0.10 + ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.1.0 + utf-8-validate: 5.0.10 + ws@8.18.3(bufferutil@4.1.0)(utf-8-validate@5.0.10): optionalDependencies: bufferutil: 4.1.0 @@ -5205,16 +9044,57 @@ snapshots: bufferutil: 4.1.0 utf-8-validate: 5.0.10 + xmlhttprequest-ssl@2.1.2: {} + + xtend@4.0.2: {} + + y18n@4.0.3: {} + yallist@3.1.1: {} + yargs-parser@18.1.3: + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + + yargs@15.4.1: + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + yocto-queue@0.1.0: {} yocto-queue@1.2.2: {} + zod@3.22.4: {} + zod@3.25.76: {} - zustand@5.0.11(@types/react@18.3.28)(react@18.3.1)(use-sync-external-store@1.2.0(react@18.3.1)): + zod@4.3.6: {} + + zustand@5.0.0(@types/react@18.3.28)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)): optionalDependencies: '@types/react': 18.3.28 react: 18.3.1 - use-sync-external-store: 1.2.0(react@18.3.1) + use-sync-external-store: 1.4.0(react@18.3.1) + + zustand@5.0.11(@types/react@18.3.28)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)): + optionalDependencies: + '@types/react': 18.3.28 + react: 18.3.1 + use-sync-external-store: 1.4.0(react@18.3.1) + + zustand@5.0.3(@types/react@18.3.28)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)): + optionalDependencies: + '@types/react': 18.3.28 + react: 18.3.1 + use-sync-external-store: 1.4.0(react@18.3.1) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 725e655..f9a8a87 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,3 +2,4 @@ packages: - 'packages/*' - 'examples/node-cli' - 'examples/browser' + - 'examples/browser-wagmi' From 8a9c5a44efe8277eea72aa8648e33d4b3f991ac9 Mon Sep 17 00:00:00 2001 From: WarTech9 Date: Wed, 25 Feb 2026 01:13:33 -0500 Subject: [PATCH 2/6] Refactor/Clean up sdk for easy integration into agent plugins --- README.md | 46 +-- examples/node-cli/README.md | 6 +- examples/node-cli/src/commands/quote.ts | 30 +- examples/node-cli/src/commands/status.ts | 53 ++- examples/node-cli/src/commands/swap.ts | 71 ++-- packages/sdk/README.md | 102 ++--- packages/sdk/src/client.ts | 98 ++--- packages/sdk/src/errors.ts | 198 +++++----- packages/sdk/src/index.ts | 19 +- packages/sdk/src/schemas.ts | 25 +- packages/sdk/src/types.ts | 241 +++++------- packages/sdk/src/utils/http.ts | 23 +- packages/sdk/src/utils/polling.ts | 18 +- packages/sdk/tests/client.test.ts | 449 +++++++++++------------ packages/sdk/tests/errors.test.ts | 193 ++++++---- packages/sdk/tests/integration.test.ts | 125 +++---- packages/sdk/tests/polling.test.ts | 17 +- packages/sdk/tests/schemas.test.ts | 52 +-- 18 files changed, 879 insertions(+), 887 deletions(-) diff --git a/README.md b/README.md index 94a0442..e2c3374 100644 --- a/README.md +++ b/README.md @@ -125,13 +125,13 @@ const client = new ClawSwapClient({ fetch: fetchWithPayment }); // 2. Execute swap const swap = await client.executeSwap({ - sourceChainId: 'solana', - sourceTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', - destinationChainId: 'base', - destinationTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + sourceChain: 'solana', + sourceToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', + destinationChain: 'base', + destinationToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', amount: '1000000', - senderAddress: 'your-solana-address', - recipientAddress: '0x-your-base-address', + userWallet: 'your-solana-address', + recipient: '0x-your-base-address', }); // 3. Sign and submit to Solana @@ -148,12 +148,12 @@ const signature = await connection.sendRawTransaction(tx.serialize(), { await connection.confirmTransaction(signature, 'confirmed'); // 4. Wait for settlement -const result = await client.waitForSettlement(swap.orderId, { +const result = await client.waitForSettlement(swap.requestId, { timeout: 300_000, interval: 3000, onStatusUpdate: (status) => console.log(`Status: ${status.status}`), }); -console.log(`Swap completed: ${result.destinationAmount} tokens delivered`); +console.log(`Swap completed: ${result.outputAmount} tokens delivered`); ``` ### Base → Solana (free, no x402) @@ -170,13 +170,13 @@ const client = new ClawSwapClient(); // 2. Execute swap const swap = await client.executeSwap({ - sourceChainId: 'base', - sourceTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', - destinationChainId: 'solana', - destinationTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', + sourceChain: 'base', + sourceToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + destinationChain: 'solana', + destinationToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', amount: '1000000', - senderAddress: '0x-your-base-address', - recipientAddress: 'your-solana-address', + userWallet: '0x-your-base-address', + recipient: 'your-solana-address', }); // 3. Sign and submit to Base (execute transactions in order) @@ -197,12 +197,12 @@ if (isEvmSource(swap)) { } // 4. Wait for settlement -const result = await client.waitForSettlement(swap.orderId, { +const result = await client.waitForSettlement(swap.requestId, { timeout: 300_000, interval: 3000, onStatusUpdate: (status) => console.log(`Status: ${status.status}`), }); -console.log(`Swap completed: ${result.destinationAmount} tokens delivered`); +console.log(`Swap completed: ${result.outputAmount} tokens delivered`); ``` ## Web App Integration @@ -233,13 +233,13 @@ const client = new ClawSwapClient(); // 3. Execute swap const swap = await client.executeSwap({ - sourceChainId: 'base', - sourceTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC - destinationChainId: 'solana', - destinationTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC + sourceChain: 'base', + sourceToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC + destinationChain: 'solana', + destinationToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC amount: '1000000', // 1 USDC - senderAddress: account, - recipientAddress: 'your-solana-address', + userWallet: account, + recipient: 'your-solana-address', }); // 4. Sign and submit with browser wallet (MetaMask will pop up) @@ -257,7 +257,7 @@ if (isEvmSource(swap)) { } // 5. Monitor settlement -const result = await client.waitForSettlement(swap.orderId, { +const result = await client.waitForSettlement(swap.requestId, { timeout: 300_000, onStatusUpdate: (s) => console.log(`Status: ${s.status}`), }); diff --git a/examples/node-cli/README.md b/examples/node-cli/README.md index 70627bf..71abfda 100644 --- a/examples/node-cli/README.md +++ b/examples/node-cli/README.md @@ -41,8 +41,6 @@ pnpm dev -- quote \ --recipient ``` -Quotes expire in 30 seconds. - ### Swap Mock mode (no wallet): @@ -69,8 +67,8 @@ pnpm dev -- swap \ ### Status ```bash -pnpm dev -- status -pnpm dev -- status --watch +pnpm dev -- status +pnpm dev -- status --watch ``` ## Token Shortcuts diff --git a/examples/node-cli/src/commands/quote.ts b/examples/node-cli/src/commands/quote.ts index 806c1ee..6310bd4 100644 --- a/examples/node-cli/src/commands/quote.ts +++ b/examples/node-cli/src/commands/quote.ts @@ -41,31 +41,27 @@ export const quoteCommand = new Command('quote') logger.info('Fetching quote...'); const quote = await client.getQuote({ - sourceChainId: source.chain, - sourceTokenAddress: sourceToken, - destinationChainId: dest.chain, - destinationTokenAddress: destToken, + sourceChain: source.chain, + sourceToken: sourceToken, + destinationChain: dest.chain, + destinationToken: destToken, amount: options.amount, - senderAddress: options.sender, - recipientAddress: options.recipient, + userWallet: options.sender, + recipient: options.recipient, slippageTolerance: slippage, }); logger.success('Quote received:'); logger.table({ - 'Quote ID': quote.quoteId, - 'Source Amount': quote.sourceAmount, - 'Destination Amount': quote.destinationAmount, - 'Bridge Fee (USD)': `$${quote.fees.bridgeFeeUsd}`, - 'x402 Fee (USD)': `$${quote.fees.x402FeeUsd}`, - 'Gas Reimbursement (est.)': `$${quote.fees.gasReimbursementEstimatedUsd}`, - 'Total Fee (USD)': `$${quote.fees.totalEstimatedFeeUsd}`, - 'Estimated Time': `${quote.estimatedTimeSeconds}s`, - 'Expires In': `${quote.expiresIn}s`, - 'Expires At': new Date(quote.expiresAt).toISOString(), + 'Estimated Output': quote.estimatedOutputFormatted, + 'Estimated Time': `${quote.estimatedTime}s`, + 'ClawSwap Fee': quote.fees.clawswap, + 'Relay Fee': quote.fees.relay, + 'Gas Fee': quote.fees.gas, + 'Route': `${quote.route.sourceChain} (${quote.route.sourceToken.symbol}) → ${quote.route.destinationChain} (${quote.route.destinationToken.symbol})`, + 'Supported': quote.supported ? 'Yes' : 'No', }); - logger.warn('Note: This quote expires in 30 seconds'); console.log(); console.log('To execute this swap, run:'); console.log(` pnpm dev -- swap --from ${options.from} --to ${options.to} --amount ${options.amount} --destination
`); diff --git a/examples/node-cli/src/commands/status.ts b/examples/node-cli/src/commands/status.ts index ffaf4ce..2f319da 100644 --- a/examples/node-cli/src/commands/status.ts +++ b/examples/node-cli/src/commands/status.ts @@ -9,18 +9,18 @@ import { config } from '../config.js'; export const statusCommand = new Command('status') .description('Check the status of a swap') - .argument('', 'Swap ID to check') + .argument('', 'Request ID to check') .option('--watch', 'Watch for status updates until completion') - .action(async (swapId: string, options) => { + .action(async (requestId: string, options) => { try { const client = new ClawSwapClient({ baseUrl: config.API_URL }); if (options.watch) { // Watch mode: poll until completion - logger.info(`Watching swap ${swapId}...`); + logger.info(`Watching swap ${requestId}...`); console.log(); - const result = await client.waitForSettlement(swapId, { + const result = await client.waitForSettlement(requestId, { timeout: 300000, // 5 minutes interval: 3000, onStatusUpdate: (status) => { @@ -34,22 +34,19 @@ export const statusCommand = new Command('status') logger.success('Swap completed!'); } else { logger.error(`Swap ${result.status}`); - if (result.failureReason) { - logger.error(`Reason: ${result.failureReason}`); - } } } else { // One-time status check - logger.info(`Fetching status for swap ${swapId}...`); - const status = await client.getStatus(swapId); + logger.info(`Fetching status for swap ${requestId}...`); + const status = await client.getStatus(requestId); console.log(); displayStatus(status); - if (!['completed', 'failed', 'expired'].includes(status.status)) { + if (!['completed', 'failed'].includes(status.status)) { console.log(); logger.info('Swap is still in progress. Use --watch to monitor it:'); - console.log(` pnpm dev -- status ${swapId} --watch`); + console.log(` pnpm dev -- status ${requestId} --watch`); } } @@ -64,32 +61,28 @@ export const statusCommand = new Command('status') */ function displayStatus(status: any) { logger.table({ - 'Swap ID': status.swapId, + 'Request ID': status.requestId, 'Status': status.status, - 'Source Chain': status.sourceChainId, - 'Source Amount': status.sourceAmount, - 'Destination Chain': status.destinationChainId, - 'Destination Amount': status.destinationAmount, + 'Source Chain': status.sourceChain, + 'Destination Chain': status.destinationChain, + 'Output Amount': status.outputAmount, }); - // Show transactions - if (status.transactions && status.transactions.length > 0) { + // Show transaction hashes if available + if (status.sourceTxHash || status.destinationTxHash) { console.log(); console.log('Transactions:'); - status.transactions.forEach((tx: any) => { - console.log(` Chain: ${tx.chainId}`); - console.log(` Hash: ${tx.txHash}`); - console.log(` Status: ${tx.status}`); - if (tx.explorerUrl) { - console.log(` Explorer: ${tx.explorerUrl}`); - } - console.log(); - }); + if (status.sourceTxHash) { + console.log(` Source TX: ${status.sourceTxHash}`); + } + if (status.destinationTxHash) { + console.log(` Destination TX: ${status.destinationTxHash}`); + } } - // Show failure reason if failed - if (status.status === 'failed' && status.failureReason) { + // Show completion time if available + if (status.completedAt) { console.log(); - logger.error(`Failure reason: ${status.failureReason}`); + console.log(` Completed at: ${status.completedAt}`); } } diff --git a/examples/node-cli/src/commands/swap.ts b/examples/node-cli/src/commands/swap.ts index 6da9f14..cea4f4d 100644 --- a/examples/node-cli/src/commands/swap.ts +++ b/examples/node-cli/src/commands/swap.ts @@ -132,22 +132,23 @@ export const swapCommand = new Command('swap') console.log(); logger.info('Step 1/3: Getting quote...'); const quote = await client.getQuote({ - sourceChainId: source.chain, - sourceTokenAddress: sourceToken, - destinationChainId: dest.chain, - destinationTokenAddress: destToken, + sourceChain: source.chain, + sourceToken: sourceToken, + destinationChain: dest.chain, + destinationToken: destToken, amount: options.amount, - senderAddress: options.sender || 'default-sender', - recipientAddress: options.destination, + userWallet: options.sender || 'default-sender', + recipient: options.destination, slippageTolerance: slippage, }); - logger.success(`Quote received: ${quote.destinationAmount} tokens`); - logger.warn(`Quote expires in ${quote.expiresIn} seconds`); + logger.success(`Quote received: ${quote.estimatedOutputFormatted}`); logger.table({ - 'Quote ID': quote.quoteId, - 'Total Fee': `$${quote.fees.totalEstimatedFeeUsd}`, - 'Estimated Time': `${quote.estimatedTimeSeconds}s`, + 'Estimated Output': quote.estimatedOutputFormatted, + 'ClawSwap Fee': quote.fees.clawswap, + 'Relay Fee': quote.fees.relay, + 'Gas Fee': quote.fees.gas, + 'Estimated Time': `${quote.estimatedTime}s`, }); // STEP 2: Execute swap @@ -157,7 +158,7 @@ export const swapCommand = new Command('swap') if (options.mock) { logger.warn('[MOCK MODE] Skipping actual swap execution'); logger.info('In real mode, this would:'); - console.log(' 1. Pay $0.50 USDC via x402'); + console.log(' 1. Pay $0.25 USDC via x402 (Solana source only)'); console.log(' 2. Initiate the cross-chain swap'); console.log(' 3. Monitor status until completion'); return; @@ -165,22 +166,25 @@ export const swapCommand = new Command('swap') // Execute swap with v2 API (no need for getTokenInfo - API handles it) const executeResponse = await client.executeSwap({ - sourceChainId: source.chain, - sourceTokenAddress: sourceToken, - destinationChainId: dest.chain, - destinationTokenAddress: destToken, + sourceChain: source.chain, + sourceToken: sourceToken, + destinationChain: dest.chain, + destinationToken: destToken, amount: options.amount, - senderAddress: options.sender || 'default-sender', - recipientAddress: options.destination, + userWallet: options.sender || 'default-sender', + recipient: options.destination, slippageTolerance: slippage, }); logger.success(`Swap transaction received!`); logger.table({ - 'Order ID': executeResponse.orderId, - 'Gas Reimbursement': executeResponse.accounting.gasReimbursement?.amountFormatted ?? 'N/A (EVM source)', - 'x402 Fee (USD)': `$${executeResponse.accounting.x402Fee.amountUsd}`, - 'Is Token-2022': executeResponse.isToken2022 ? 'Yes' : 'No', + 'Request ID': executeResponse.requestId, + 'Source Chain': executeResponse.sourceChain, + 'Estimated Output': executeResponse.estimatedOutput, + 'ClawSwap Fee': executeResponse.fees.clawswap, + 'Relay Fee': executeResponse.fees.relay, + 'Gas Fee': executeResponse.fees.gas, + 'Instructions': executeResponse.instructions, }); console.log(); @@ -346,13 +350,13 @@ export const swapCommand = new Command('swap') } - // STEP 3: Monitor status (using order ID from execute response) + // STEP 3: Monitor status (using request ID from execute response) console.log(); logger.info('Step 3/3: Monitoring swap status...'); logger.info('This may take several minutes depending on network congestion'); console.log(); - const result = await client.waitForSettlement(executeResponse.orderId, { + const result = await client.waitForSettlement(executeResponse.requestId, { timeout: 300000, // 5 minutes interval: 3000, // 3 seconds onStatusUpdate: (status) => { @@ -365,32 +369,25 @@ export const swapCommand = new Command('swap') if (status.destinationTxHash) { console.log(` Destination TX: ${status.destinationTxHash}`); } - if (status.explorerUrl) { - console.log(` Explorer: ${status.explorerUrl}`); - } }, }); console.log(); - if (result.status === 'fulfilled' || result.status === 'completed') { - logger.success('✨ Swap completed successfully!'); + if (result.status === 'completed') { + logger.success('Swap completed successfully!'); logger.table({ - 'Order ID': result.orderId, + 'Request ID': result.requestId, 'Status': result.status, - 'Source Amount': result.sourceAmount, - 'Destination Amount': result.destinationAmount, + 'Output Amount': result.outputAmount, 'Destination Address': options.destination, }); - if (result.explorerUrl) { + if (result.completedAt) { console.log(); - logger.info(`View on explorer: ${result.explorerUrl}`); + logger.info(`Completed at: ${result.completedAt}`); } } else { logger.error(`Swap ${result.status}`); - if (result.failureReason) { - logger.error(`Reason: ${result.failureReason}`); - } process.exit(1); } diff --git a/packages/sdk/README.md b/packages/sdk/README.md index c97ce07..786db49 100644 --- a/packages/sdk/README.md +++ b/packages/sdk/README.md @@ -82,13 +82,13 @@ const client = new ClawSwapClient({ fetch: fetchWithPayment }); // 2. Execute swap const swap = await client.executeSwap({ - sourceChainId: 'solana', - sourceTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', - destinationChainId: 'base', - destinationTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + sourceChain: 'solana', + sourceToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', + destinationChain: 'base', + destinationToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', amount: '1000000', // 1 USDC (6 decimals) - senderAddress: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', - recipientAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', + userWallet: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', + recipient: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', }); // 3. Sign and submit (Solana source returns base64 string) @@ -100,7 +100,7 @@ const signature = await connection.sendRawTransaction(tx.serialize()); await connection.confirmTransaction(signature); // 4. Wait for completion -const result = await client.waitForSettlement(swap.orderId); +const result = await client.waitForSettlement(swap.requestId); console.log(`Swap ${result.status}!`); ``` @@ -118,13 +118,13 @@ const client = new ClawSwapClient(); // 2. Execute swap const swap = await client.executeSwap({ - sourceChainId: 'base', - sourceTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', - destinationChainId: 'solana', - destinationTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', + sourceChain: 'base', + sourceToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + destinationChain: 'solana', + destinationToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', amount: '1000000', - senderAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', - recipientAddress: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', + userWallet: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', + recipient: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', }); // 3. Sign and submit (Base source returns ordered transactions array) @@ -145,7 +145,7 @@ if (isEvmSource(swap)) { } // 4. Wait for completion -const result = await client.waitForSettlement(swap.orderId); +const result = await client.waitForSettlement(swap.requestId); console.log(`Swap ${result.status}!`); ``` @@ -155,7 +155,6 @@ console.log(`Swap ${result.status}!`); - ✅ **x402 Compatible** - Accepts x402-wrapped fetch for automatic payment handling - ✅ **Status Polling** - `waitForSettlement()` polls until swap completes - ✅ **Typed Errors** - Specific error classes for each failure type -- ✅ **Quote Expiry Tracking** - `expiresIn` field shows seconds until quote expires - ✅ **Discovery Helpers** - Methods to get supported chains, tokens, and pairs - ✅ **Framework Agnostic** - Works with any fetch implementation @@ -196,13 +195,13 @@ Get a quote for a cross-chain swap. **Free endpoint**. ```typescript const quote = await client.getQuote({ - sourceChainId: 'solana', - sourceTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', - destinationChainId: 'base', - destinationTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + sourceChain: 'solana', + sourceToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', + destinationChain: 'base', + destinationToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', amount: '1000000', // 1 USDC (6 decimals) - senderAddress: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', - recipientAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', + userWallet: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', + recipient: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', slippageTolerance: 0.01, // Optional, 1% }); ``` @@ -231,26 +230,26 @@ if (isEvmSource(response)) { // Solana source → deserialize base64, sign, submit to Solana } -console.log(response.orderId); // Use for status tracking +console.log(response.requestId); // Use for status tracking ``` -##### `getStatus(orderId: string): Promise` +##### `getStatus(requestId: string): Promise` -Check the status of a swap using the order ID. **Free endpoint**. +Check the status of a swap using the request ID. **Free endpoint**. ```typescript -// Use orderId from executeSwap response -const status = await client.getStatus(response.orderId); -console.log(status.status); // 'pending' | 'created' | 'fulfilled' | 'completed' | 'failed' | 'cancelled' +// Use requestId from executeSwap response +const status = await client.getStatus(response.requestId); +console.log(status.status); // 'pending' | 'submitted' | 'filling' | 'completed' | 'failed' ``` -##### `waitForSettlement(orderId: string, options?): Promise` +##### `waitForSettlement(requestId: string, options?): Promise` -Poll until swap reaches a terminal state (fulfilled/completed/failed/cancelled). +Poll until swap reaches a terminal state (completed/failed). ```typescript -// Use orderId from executeSwap response -const result = await client.waitForSettlement(response.orderId, { +// Use requestId from executeSwap response +const result = await client.waitForSettlement(response.requestId, { timeout: 300000, // 5 minutes (default) interval: 3000, // Poll every 3 seconds (default) onStatusUpdate: (status) => { @@ -292,7 +291,6 @@ The SDK throws typed errors for specific failure scenarios: import { ClawSwapError, InsufficientLiquidityError, - QuoteExpiredError, PaymentRequiredError } from '@clawswap/sdk'; @@ -300,9 +298,7 @@ try { await client.executeSwap(request); } catch (error) { if (error instanceof InsufficientLiquidityError) { - console.error('Not enough liquidity:', error.details); - } else if (error instanceof QuoteExpiredError) { - console.error('Quote expired, get a new one'); + console.error('Not enough liquidity:', error.suggestion); } else if (error instanceof PaymentRequiredError) { console.error('Payment failed:', error.message); } else if (error instanceof ClawSwapError) { @@ -312,39 +308,19 @@ try { ``` **Available Error Classes:** +- `MissingFieldError` - Required field missing from request +- `UnsupportedChainError` - Chain not supported +- `UnsupportedRouteError` - Token pair/route not supported +- `QuoteFailedError` - Failed to get quote - `InsufficientLiquidityError` - Not enough liquidity for swap - `AmountTooLowError` / `AmountTooHighError` - Amount outside limits -- `UnsupportedPairError` - Token pair not supported -- `QuoteExpiredError` - Quote expired (30s TTL) -- `PaymentRequiredError` / `PaymentVerificationError` - x402 payment issues +- `GasExceedsThresholdError` - Gas cost exceeds safety threshold +- `RelayUnavailableError` - Relay bridge service unavailable +- `PaymentRequiredError` - x402 payment required (Solana-source swaps) +- `RateLimitExceededError` - Too many requests - `NetworkError` - Network request failed - `TimeoutError` - Request or polling timed out -## Quote Expiry - -When using `getQuote()` for preview, quotes expire in **30 seconds**. The SDK includes `expiresIn` and `expiresAt` fields: - -```typescript -const quote = await client.getQuote(request); -console.log(`Quote expires in ${quote.expiresIn} seconds`); -console.log(`Estimated output: ${quote.destinationAmount} tokens`); -``` - -**Note:** Quote expiry is NOT an issue when executing swaps. The `executeSwap()` method fetches a fresh quote internally, so you don't need to worry about timing: - -```typescript -// No quote expiry issues - API fetches fresh quote -const executeResponse = await client.executeSwap({ - sourceChainId: 'solana', - sourceTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', - destinationChainId: 'base', - destinationTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', - amount: '1000000', - senderAddress: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', - recipientAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', -}); -``` - ## Usage Without x402 The SDK works with standard fetch too (for free endpoints): diff --git a/packages/sdk/src/client.ts b/packages/sdk/src/client.ts index 4c28a21..0aab0fd 100644 --- a/packages/sdk/src/client.ts +++ b/packages/sdk/src/client.ts @@ -10,12 +10,13 @@ import type { TokenPair, SwapFeeBreakdown, } from './types'; +import { UnsupportedChainError, NetworkError } from './errors'; import { HttpClient } from './utils/http'; import { poll, isTerminalStatus } from './utils/polling'; import { quoteRequestSchema, statusRequestSchema } from './schemas'; /** - * ClawSwap SDK Client + * ClawSwap SDK Client (v2) * * Framework-agnostic TypeScript client for ClawSwap cross-chain swaps. * Accepts x402-wrapped fetch function for payment handling. @@ -30,21 +31,28 @@ import { quoteRequestSchema, statusRequestSchema } from './schemas'; * * // Get a quote * const quote = await client.getQuote({ - * sourceChainId: 'solana', - * sourceTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', - * destinationChainId: 'base', - * destinationTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + * sourceChain: 'solana', + * sourceToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', + * destinationChain: 'base', + * destinationToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', * amount: '1000000', + * userWallet: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', + * recipient: '0x07150e919b4de5fd6a63de1f9384828396f25fdc', * }); * * // Execute swap * const swap = await client.executeSwap({ - * ...quote, - * destinationAddress: '0x...', + * sourceChain: 'solana', + * sourceToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', + * destinationChain: 'base', + * destinationToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + * amount: '1000000', + * userWallet: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', + * recipient: '0x07150e919b4de5fd6a63de1f9384828396f25fdc', * }); * * // Wait for settlement - * const result = await client.waitForSettlement(swap.swapId); + * const result = await client.waitForSettlement(swap.requestId); * ``` */ export class ClawSwapClient { @@ -73,10 +81,10 @@ export class ClawSwapClient { * * Returns transaction data that must be signed and submitted: * - Solana source: base64 string → deserialize, sign, submit to Solana RPC - * - Base source: ordered EvmTransaction[] array → execute sequentially with viem/ethers on Base + * - Base source: ordered EvmTransaction[] array → execute sequentially on Base * * @param request Same parameters as getQuote() - * @returns Transaction to sign and orderId for tracking + * @returns Transaction to sign and requestId for tracking */ async executeSwap(request: QuoteRequest): Promise { const validated = quoteRequestSchema.parse(request); @@ -84,32 +92,33 @@ export class ClawSwapClient { } /** - * Get the status of a swap using the order ID (quote ID) + * Get the status of a swap * Free endpoint - no x402 payment required * - * @param orderId The order ID (same as the quote ID) + * @param requestId The request ID returned from executeSwap() */ - async getStatus(orderId: string): Promise { - const validated = statusRequestSchema.parse({ orderId }); - return this.http.get(`/api/swap/${orderId}/status`); + async getStatus(requestId: string): Promise { + const validated = statusRequestSchema.parse({ requestId }); + return this.http.get(`/api/swap/${validated.requestId}/status`); } /** - * Wait for swap to reach terminal status (fulfilled/completed/failed/cancelled) + * Wait for swap to reach terminal status (completed or failed) * Polls every 3 seconds by default * - * @param orderId The order ID (same as the quote ID) + * @param requestId The request ID returned from executeSwap() */ async waitForSettlement( - orderId: string, + requestId: string, options: WaitForSettlementOptions = {} ): Promise { return poll( - () => this.getStatus(orderId), - (status) => { + async () => { + const status = await this.getStatus(requestId); options.onStatusUpdate?.(status); - return !isTerminalStatus(status.status); + return status; }, + (status) => !isTerminalStatus(status.status), options ); } @@ -127,7 +136,10 @@ export class ClawSwapClient { * Free endpoint - cached for 1 hour */ async getSupportedChains(): Promise { - const response = await this.http.get<{ chains: Chain[] }>('/api/chains'); + const response = await this.http.get<{ chains?: Chain[] }>('/api/chains'); + if (!Array.isArray(response.chains)) { + throw new NetworkError('Unexpected API response: missing chains array'); + } return response.chains; } @@ -136,27 +148,40 @@ export class ClawSwapClient { * Free endpoint - cached for 1 hour */ async getSupportedTokens(chainId: string): Promise { - const response = await this.http.get<{ tokens: Token[] }>(`/api/tokens/${chainId}`); + if (!/^[a-zA-Z0-9_-]+$/.test(chainId)) { + throw new UnsupportedChainError(`Invalid chain ID: ${chainId}`); + } + const response = await this.http.get<{ tokens?: Token[] }>(`/api/tokens/${chainId}`); + if (!Array.isArray(response.tokens)) { + throw new NetworkError('Unexpected API response: missing tokens array'); + } return response.tokens; } /** * Get all valid cross-chain swap pairs - * Derives pairs from supported chains and tokens - * Results are computed client-side from cached chain/token data + * Fetches each chain's tokens once, then computes pairs in-memory * * @returns Array of valid swap pairs */ async getSupportedPairs(): Promise { const chains = await this.getSupportedChains(); - const pairs: TokenPair[] = []; + // Fetch each chain's tokens exactly once + const tokensByChain = new Map(); + await Promise.all( + chains.map(async (chain) => { + tokensByChain.set(chain.id, await this.getSupportedTokens(chain.id)); + }) + ); + + const pairs: TokenPair[] = []; for (const sourceChain of chains) { - const sourceTokens = await this.getSupportedTokens(sourceChain.id); + const sourceTokens = tokensByChain.get(sourceChain.id) ?? []; for (const sourceToken of sourceTokens) { for (const destChain of chains) { - if (sourceChain.id === destChain.id) continue; // Skip same-chain - const destTokens = await this.getSupportedTokens(destChain.id); + if (sourceChain.id === destChain.id) continue; + const destTokens = tokensByChain.get(destChain.id) ?? []; for (const destToken of destTokens) { pairs.push({ sourceChain, @@ -171,19 +196,4 @@ export class ClawSwapClient { return pairs; } - - /** - * Get token information including decimals - * Helper method for executing swaps - * @private - */ - private async getTokenInfo(chainId: string, tokenAddress: string): Promise { - const tokens = await this.getSupportedTokens(chainId); - const token = tokens.find(t => t.address === tokenAddress); - if (!token) { - throw new Error(`Token ${tokenAddress} not found on chain ${chainId}`); - } - return token; - } - } diff --git a/packages/sdk/src/errors.ts b/packages/sdk/src/errors.ts index 9e46d0a..6756c81 100644 --- a/packages/sdk/src/errors.ts +++ b/packages/sdk/src/errors.ts @@ -1,175 +1,193 @@ import type { ErrorCode, ApiError } from './types'; /** - * Base error class for all ClawSwap SDK errors + * Base error class for all ClawSwap SDK errors (v2) */ export class ClawSwapError extends Error { public readonly code: ErrorCode; - public readonly details?: Record; + public readonly suggestion?: string; - constructor(code: ErrorCode, message: string, details?: Record) { + constructor(code: ErrorCode, message: string, suggestion?: string) { super(message); this.name = 'ClawSwapError'; this.code = code; - this.details = details; + this.suggestion = suggestion; Object.setPrototypeOf(this, ClawSwapError.prototype); } toJSON(): ApiError { return { - code: this.code, - message: this.message, - details: this.details, + error: { + code: this.code, + message: this.message, + ...(this.suggestion && { suggestion: this.suggestion }), + }, }; } } -/** - * Thrown when insufficient liquidity is available for the swap - */ +export class MissingFieldError extends ClawSwapError { + constructor(message = 'Missing required field', suggestion?: string) { + super('MISSING_FIELD', message, suggestion); + this.name = 'MissingFieldError'; + Object.setPrototypeOf(this, MissingFieldError.prototype); + } +} + +export class UnsupportedChainError extends ClawSwapError { + constructor(message = 'Chain not supported', suggestion?: string) { + super('UNSUPPORTED_CHAIN', message, suggestion); + this.name = 'UnsupportedChainError'; + Object.setPrototypeOf(this, UnsupportedChainError.prototype); + } +} + +export class UnsupportedRouteError extends ClawSwapError { + constructor(message = 'This route is not supported', suggestion?: string) { + super('UNSUPPORTED_ROUTE', message, suggestion); + this.name = 'UnsupportedRouteError'; + Object.setPrototypeOf(this, UnsupportedRouteError.prototype); + } +} + +export class QuoteFailedError extends ClawSwapError { + constructor(message = 'Failed to get quote', suggestion?: string) { + super('QUOTE_FAILED', message, suggestion); + this.name = 'QuoteFailedError'; + Object.setPrototypeOf(this, QuoteFailedError.prototype); + } +} + export class InsufficientLiquidityError extends ClawSwapError { - constructor(message = 'Insufficient liquidity for this swap', details?: Record) { - super('INSUFFICIENT_LIQUIDITY', message, details); + constructor(message = 'Insufficient liquidity for this swap', suggestion?: string) { + super('INSUFFICIENT_LIQUIDITY', message, suggestion); this.name = 'InsufficientLiquidityError'; Object.setPrototypeOf(this, InsufficientLiquidityError.prototype); } } -/** - * Thrown when the swap amount is below minimum - */ export class AmountTooLowError extends ClawSwapError { - constructor(message = 'Amount is below minimum', details?: Record) { - super('AMOUNT_TOO_LOW', message, details); + constructor(message = 'Amount is below minimum', suggestion?: string) { + super('AMOUNT_TOO_LOW', message, suggestion); this.name = 'AmountTooLowError'; Object.setPrototypeOf(this, AmountTooLowError.prototype); } } -/** - * Thrown when the swap amount exceeds maximum - */ export class AmountTooHighError extends ClawSwapError { - constructor(message = 'Amount exceeds maximum', details?: Record) { - super('AMOUNT_TOO_HIGH', message, details); + constructor(message = 'Amount exceeds maximum', suggestion?: string) { + super('AMOUNT_TOO_HIGH', message, suggestion); this.name = 'AmountTooHighError'; Object.setPrototypeOf(this, AmountTooHighError.prototype); } } -/** - * Thrown when the token pair is not supported - */ -export class UnsupportedPairError extends ClawSwapError { - constructor(message = 'This token pair is not supported', details?: Record) { - super('UNSUPPORTED_PAIR', message, details); - this.name = 'UnsupportedPairError'; - Object.setPrototypeOf(this, UnsupportedPairError.prototype); +export class GasExceedsThresholdError extends ClawSwapError { + constructor(message = 'Gas cost exceeds safety threshold', suggestion?: string) { + super('GAS_EXCEEDS_THRESHOLD', message, suggestion); + this.name = 'GasExceedsThresholdError'; + Object.setPrototypeOf(this, GasExceedsThresholdError.prototype); } } -/** - * Thrown when a quote has expired (30s TTL) - */ -export class QuoteExpiredError extends ClawSwapError { - constructor( - message = 'Quote has expired, please request a new quote', - details?: Record - ) { - super('QUOTE_EXPIRED', message, details); - this.name = 'QuoteExpiredError'; - Object.setPrototypeOf(this, QuoteExpiredError.prototype); +export class RelayUnavailableError extends ClawSwapError { + constructor(message = 'Relay bridge service unavailable', suggestion?: string) { + super('RELAY_UNAVAILABLE', message, suggestion); + this.name = 'RelayUnavailableError'; + Object.setPrototypeOf(this, RelayUnavailableError.prototype); } } -/** - * Thrown when payment is required but not provided - */ export class PaymentRequiredError extends ClawSwapError { - constructor(message = 'Payment required to execute swap', details?: Record) { - super('PAYMENT_REQUIRED', message, details); + constructor(message = 'Payment required to execute swap', suggestion?: string) { + super('PAYMENT_REQUIRED', message, suggestion); this.name = 'PaymentRequiredError'; Object.setPrototypeOf(this, PaymentRequiredError.prototype); } } -/** - * Thrown when payment verification fails - */ -export class PaymentVerificationError extends ClawSwapError { - constructor(message = 'Payment verification failed', details?: Record) { - super('PAYMENT_VERIFICATION_FAILED', message, details); - this.name = 'PaymentVerificationError'; - Object.setPrototypeOf(this, PaymentVerificationError.prototype); +export class RateLimitExceededError extends ClawSwapError { + constructor(message = 'Rate limit exceeded', suggestion?: string) { + super('RATE_LIMIT_EXCEEDED', message, suggestion); + this.name = 'RateLimitExceededError'; + Object.setPrototypeOf(this, RateLimitExceededError.prototype); } } -/** - * Thrown when network request fails - */ export class NetworkError extends ClawSwapError { - constructor(message = 'Network request failed', details?: Record) { - super('NETWORK_ERROR', message, details); + constructor(message = 'Network request failed', suggestion?: string) { + super('NETWORK_ERROR', message, suggestion); this.name = 'NetworkError'; Object.setPrototypeOf(this, NetworkError.prototype); } } -/** - * Thrown when request times out - */ export class TimeoutError extends ClawSwapError { - constructor(message = 'Request timed out', details?: Record) { - super('TIMEOUT', message, details); + constructor(message = 'Request timed out', suggestion?: string) { + super('TIMEOUT', message, suggestion); this.name = 'TimeoutError'; Object.setPrototypeOf(this, TimeoutError.prototype); } } /** - * Maps HTTP error responses to typed error classes + * Maps HTTP error responses to typed error classes. + * Parses the v2 error envelope: { error: { code, message, suggestion } } */ -export function mapApiError(statusCode: number, errorData: Partial): ClawSwapError { - const { code, message, details } = errorData; +export function mapApiError(statusCode: number, errorData: unknown): ClawSwapError { + const envelope = (errorData != null && typeof errorData === 'object' ? errorData : {}) as { + error?: { code?: string; message?: string; suggestion?: string }; + }; + const code = envelope?.error?.code; + const message = envelope?.error?.message; + const suggestion = envelope?.error?.suggestion; - // If we have a specific error code, use it if (code) { switch (code) { + case 'MISSING_FIELD': + return new MissingFieldError(message, suggestion); + case 'UNSUPPORTED_CHAIN': + return new UnsupportedChainError(message, suggestion); + case 'UNSUPPORTED_ROUTE': + return new UnsupportedRouteError(message, suggestion); + case 'QUOTE_FAILED': + return new QuoteFailedError(message, suggestion); case 'INSUFFICIENT_LIQUIDITY': - return new InsufficientLiquidityError(message, details); + return new InsufficientLiquidityError(message, suggestion); case 'AMOUNT_TOO_LOW': - return new AmountTooLowError(message, details); + return new AmountTooLowError(message, suggestion); case 'AMOUNT_TOO_HIGH': - return new AmountTooHighError(message, details); - case 'UNSUPPORTED_PAIR': - return new UnsupportedPairError(message, details); - case 'QUOTE_EXPIRED': - return new QuoteExpiredError(message, details); + return new AmountTooHighError(message, suggestion); + case 'GAS_EXCEEDS_THRESHOLD': + return new GasExceedsThresholdError(message, suggestion); + case 'RELAY_UNAVAILABLE': + return new RelayUnavailableError(message, suggestion); case 'PAYMENT_REQUIRED': - return new PaymentRequiredError(message, details); - case 'PAYMENT_VERIFICATION_FAILED': - return new PaymentVerificationError(message, details); + return new PaymentRequiredError(message, suggestion); + case 'RATE_LIMIT_EXCEEDED': + return new RateLimitExceededError(message, suggestion); case 'NETWORK_ERROR': - return new NetworkError(message, details); + return new NetworkError(message, suggestion); case 'TIMEOUT': - return new TimeoutError(message, details); + return new TimeoutError(message, suggestion); default: - return new ClawSwapError(code, message || 'An error occurred', details); + return new ClawSwapError(code as ErrorCode, message || 'An error occurred', suggestion); } } - // Fallback to HTTP status code mapping + // Fallback: HTTP status code mapping if (statusCode === 402) { - return new PaymentRequiredError(message || 'Payment required', details); + return new PaymentRequiredError(message || 'Payment required', suggestion); + } + if (statusCode === 404) { + return new ClawSwapError('UNSUPPORTED_ROUTE' as ErrorCode, message || 'Resource not found', suggestion); + } + if (statusCode === 429) { + return new RateLimitExceededError(message || 'Rate limit exceeded', suggestion); } - if (statusCode >= 500) { - return new ClawSwapError( - 'SERVER_CONFIGURATION_ERROR', - message || 'Server error occurred', - details - ); + return new RelayUnavailableError(message || 'Server error occurred', suggestion); } - return new ClawSwapError('UNKNOWN_ERROR', message || 'Unknown error occurred', details); + return new ClawSwapError('NETWORK_ERROR' as ErrorCode, message || 'Unknown error occurred', suggestion); } diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 2bb8aeb..b21d530 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -8,36 +8,37 @@ export type { QuoteResponse, ExecuteSwapResponse, EvmTransaction, - SwapResponse, // Alias for ExecuteSwapResponse (backwards compatibility) StatusResponse, SwapFeeBreakdown, - SwapFeeResponse, // Deprecated alias for SwapFeeBreakdown WaitForSettlementOptions, Chain, Token, TokenPair, SwapStatus, - SwapTransaction, ErrorCode, ApiError, } from './types'; -// Type guards and helpers -export { isEvmTransaction, isEvmSource, isSolanaSource } from './types'; +// Type guards +export { isEvmSource, isSolanaSource } from './types'; // Errors export { ClawSwapError, + MissingFieldError, + UnsupportedChainError, + UnsupportedRouteError, + QuoteFailedError, InsufficientLiquidityError, AmountTooLowError, AmountTooHighError, - UnsupportedPairError, - QuoteExpiredError, + GasExceedsThresholdError, + RelayUnavailableError, PaymentRequiredError, - PaymentVerificationError, + RateLimitExceededError, NetworkError, TimeoutError, } from './errors'; -// Schemas (for external validation if needed) +// Schemas (for MCP tool input schemas, GOAT plugin validation) export { quoteRequestSchema, statusRequestSchema } from './schemas'; diff --git a/packages/sdk/src/schemas.ts b/packages/sdk/src/schemas.ts index e2d1770..7f9f194 100644 --- a/packages/sdk/src/schemas.ts +++ b/packages/sdk/src/schemas.ts @@ -1,7 +1,7 @@ import { z } from 'zod'; /** - * Zod schemas for request/response validation + * Zod schemas for request/response validation (v2) */ // Chain ID validation @@ -10,11 +10,12 @@ export const chainIdSchema = z.string().min(1, 'Chain ID is required'); // Token address validation (supports EVM and Solana) export const tokenAddressSchema = z.string().min(1, 'Token address is required'); -// Amount validation (positive number as string) +// Amount validation (positive finite number as string, no scientific notation) export const amountSchema = z.string().refine( (val) => { + if (/[eE]/.test(val)) return false; const num = parseFloat(val); - return !isNaN(num) && num > 0; + return Number.isFinite(num) && num > 0; }, { message: 'Amount must be a positive number' } ); @@ -31,21 +32,21 @@ export const addressSchema = z.string().min(1, 'Address is required').refine( { message: 'Invalid address format (must be EVM 0x... or Solana base58)' } ); -// Quote request schema +// Quote request schema (v2 field names) export const quoteRequestSchema = z.object({ - sourceChainId: chainIdSchema, - sourceTokenAddress: tokenAddressSchema, - destinationChainId: chainIdSchema, - destinationTokenAddress: tokenAddressSchema, + sourceChain: chainIdSchema, + sourceToken: tokenAddressSchema, + destinationChain: chainIdSchema, + destinationToken: tokenAddressSchema, amount: amountSchema, - senderAddress: addressSchema, - recipientAddress: addressSchema, + userWallet: addressSchema, + recipient: addressSchema, slippageTolerance: z.number().min(0).max(1).optional(), }); -// Status request schema +// Status request schema (v2 field names) export const statusRequestSchema = z.object({ - orderId: z.string().min(1, 'Order ID is required'), + requestId: z.string().min(1, 'Request ID is required'), }); export type QuoteRequestInput = z.infer; diff --git a/packages/sdk/src/types.ts b/packages/sdk/src/types.ts index 6d7e15a..09de617 100644 --- a/packages/sdk/src/types.ts +++ b/packages/sdk/src/types.ts @@ -1,6 +1,6 @@ /** - * Core types for ClawSwap SDK - * Generated from OpenAPI spec with manual refinements + * Core types for ClawSwap SDK v2 + * Aligned with the v2 API at api.clawswap.dev */ // ============================================================================ @@ -18,32 +18,6 @@ export interface Chain { isTestnet?: boolean; } -export interface SwapFeeBreakdown { - x402Fee: { - amountUsd: number; - currency: string; - network: string; - appliesTo: string; - description: string; - }; - gasReimbursement: { - estimatedUsd: string; - currency: string; - appliesTo: string; - description: string; - }; - bridgeFee: { - estimatedUsd: string; - currency: string; - appliesTo: string; - description: string; - }; - note: string; -} - -/** @deprecated Use SwapFeeBreakdown */ -export type SwapFeeResponse = SwapFeeBreakdown; - export interface Token { address: string; symbol: string; @@ -65,23 +39,37 @@ export interface TokenPair { destinationToken: Token; } +export interface SwapFeeBreakdown { + x402Fee: { + amountUsd: number; + currency: string; + network: string; + appliesTo: string; + description: string; + }; + gasReimbursement: null | Record; + bridgeFee: { + estimatedUsd: string; + currency: string; + appliesTo: string; + description: string; + }; + note: string; +} + // ============================================================================ // Request Types // ============================================================================ export interface QuoteRequest { - sourceChainId: string; - sourceTokenAddress: string; - destinationChainId: string; - destinationTokenAddress: string; - amount: string; // String to handle big numbers - senderAddress: string; // Sender's wallet address on source chain - recipientAddress: string; // Recipient's wallet address on destination chain - slippageTolerance?: number; // Optional, 0-1 (e.g., 0.01 = 1%) -} - -export interface StatusRequest { - orderId: string; + sourceChain: string; + sourceToken: string; + destinationChain: string; + destinationToken: string; + amount: string; + userWallet: string; + recipient: string; + slippageTolerance?: number; } // ============================================================================ @@ -89,18 +77,21 @@ export interface StatusRequest { // ============================================================================ export interface QuoteResponse { - quoteId: string; - sourceAmount: string; - destinationAmount: string; + estimatedOutput: string; + estimatedOutputFormatted: string; + estimatedTime: number; fees: { - bridgeFeeUsd: number; - x402FeeUsd: number; - gasReimbursementEstimatedUsd: number; - totalEstimatedFeeUsd: number; + clawswap: string; + relay: string; + gas: string; }; - estimatedTimeSeconds: number; - expiresAt: string; // ISO 8601 timestamp - expiresIn: number; // Seconds until expiry (30s) + route: { + sourceChain: string; + sourceToken: { symbol: string; address: string; decimals: number }; + destinationChain: string; + destinationToken: { symbol: string; address: string; decimals: number }; + }; + supported: boolean; } /** EVM transaction object returned for Base → Solana swaps */ @@ -115,6 +106,8 @@ export interface EvmTransaction { chainId: number; /** Human-readable step description (e.g. "Approve USDC spending") */ description?: string; + /** Optional gas limit hint */ + gas?: string; } /** @@ -125,153 +118,99 @@ export interface EvmTransaction { * - EVM source: `transactions` is an ordered array of EVM transactions to execute sequentially */ export interface ExecuteSwapResponse { + /** Request ID for tracking swap status via /api/swap/:id/status */ + requestId: string; /** Base64-encoded partially-signed Solana transaction (Solana source only) */ transaction?: string; /** Ordered array of EVM transactions to execute sequentially (EVM source only) */ transactions?: EvmTransaction[]; - /** Order ID for tracking swap status via /api/swap/:id/status */ - orderId: string; - /** Whether the source token is Token-2022 (always false for EVM source) */ - isToken2022: boolean; - /** Detailed fee and amount accounting */ - accounting: { - x402Fee: { - amountUsd: number; - currency: string; - recipient: string; - note: string; - }; - /** Gas reimbursement details. null for EVM-source swaps (no gas sponsorship). */ - gasReimbursement: { - amountRaw: string; - amountFormatted: string; - tokenMint: string; - recipient: string; - note: string; - } | null; - bridgeFee: { - estimatedUsd: number; - note: string; - }; - sourceAmount: string; - destinationAmount: string; + /** Source chain identifier */ + sourceChain: string; + /** Estimated output amount in smallest units */ + estimatedOutput: string; + /** Estimated settlement time in seconds */ + estimatedTime: number; + /** Fee breakdown */ + fees: { + clawswap: string; + relay: string; + gas: string; }; + /** Human-readable instructions for signing and submitting */ + instructions: string; } /** Check if the execute response is from a Solana source swap */ export function isSolanaSource( response: ExecuteSwapResponse ): response is ExecuteSwapResponse & { transaction: string } { - return typeof response.transaction === 'string'; + return typeof response.transaction === 'string' && !Array.isArray(response.transactions); } /** Check if the execute response is from an EVM source swap */ export function isEvmSource( response: ExecuteSwapResponse ): response is ExecuteSwapResponse & { transactions: EvmTransaction[] } { - return Array.isArray(response.transactions); + return Array.isArray(response.transactions) && typeof response.transaction !== 'string'; } /** - * @deprecated Use `isEvmSource(response)` instead. The API now returns - * `transactions` (array) for EVM source, not a single `transaction` object. - */ -export function isEvmTransaction( - tx: unknown -): tx is EvmTransaction { - if (typeof tx !== 'object' || tx === null) return false; - const candidate = tx as Record; - return ( - typeof candidate.to === 'string' && - typeof candidate.data === 'string' && - typeof candidate.value === 'string' && - typeof candidate.chainId === 'number' - ); -} - -/** - * Swap statuses from Relay API - * Maps to Relay's order statuses + * Swap status values from the v2 API */ export type SwapStatus = - | 'pending' // Order created but not yet submitted - | 'created' // Order submitted to Relay - | 'fulfilled' // Destination transaction confirmed - | 'completed' // Same as fulfilled (alias) - | 'cancelled' // Order cancelled - | 'failed'; // Order failed - -export interface SwapTransaction { - chainId: string; - txHash: string; - status: 'pending' | 'confirmed' | 'failed'; - confirmations?: number; - explorerUrl?: string; -} + | 'pending' + | 'submitted' + | 'filling' + | 'completed' + | 'failed'; /** * Response from GET /api/swap/:id/status - * Based on Relay's OrderInfo structure */ export interface StatusResponse { - /** Order ID (same as quote ID) */ - orderId: string; - /** Current order status */ + /** Request ID */ + requestId: string; + /** Current swap status */ status: SwapStatus; - /** Source chain ID */ - sourceChainId: string; - /** Destination chain ID */ - destinationChainId: string; - /** Source amount in smallest unit */ - sourceAmount: string; - /** Destination amount in smallest unit */ - destinationAmount: string; + /** Source chain identifier */ + sourceChain: string; + /** Destination chain identifier */ + destinationChain: string; + /** Output amount in smallest units */ + outputAmount: string; /** Source chain transaction hash */ sourceTxHash?: string; /** Destination chain transaction hash */ destinationTxHash?: string; - /** Block explorer URL for destination transaction */ - explorerUrl?: string; - /** Order creation timestamp */ - createdAt: string; - /** Last update timestamp */ - updatedAt: string; - /** Estimated completion time */ - estimatedCompletionTime?: string; - /** Failure reason if status is 'failed' */ - failureReason?: string; + /** Completion timestamp (ISO 8601) */ + completedAt?: string; } -// For backwards compatibility during migration -export type SwapResponse = ExecuteSwapResponse; - // ============================================================================ // Error Types // ============================================================================ export type ErrorCode = + | 'MISSING_FIELD' + | 'UNSUPPORTED_CHAIN' + | 'UNSUPPORTED_ROUTE' + | 'QUOTE_FAILED' | 'INSUFFICIENT_LIQUIDITY' | 'AMOUNT_TOO_LOW' | 'AMOUNT_TOO_HIGH' - | 'UNSUPPORTED_PAIR' - | 'QUOTE_EXPIRED' - | 'INVALID_TOKEN_ADDRESS' - | 'INVALID_MINT_ADDRESS' - | 'INVALID_CHAIN_ID' + | 'GAS_EXCEEDS_THRESHOLD' + | 'RELAY_UNAVAILABLE' | 'PAYMENT_REQUIRED' - | 'PAYMENT_VERIFICATION_FAILED' - | 'SERVER_CONFIGURATION_ERROR' - | 'BRIDGE_API_ERROR' - | 'PRICE_FEED_UNAVAILABLE' + | 'RATE_LIMIT_EXCEEDED' | 'NETWORK_ERROR' - | 'TIMEOUT' - | 'TOKEN_2022_FEE_ERROR' - | 'UNKNOWN_ERROR'; + | 'TIMEOUT'; export interface ApiError { - code: ErrorCode; - message: string; - details?: Record; + error: { + code: ErrorCode; + message: string; + suggestion?: string; + }; } // ============================================================================ diff --git a/packages/sdk/src/utils/http.ts b/packages/sdk/src/utils/http.ts index 9c2dedf..ae80a44 100644 --- a/packages/sdk/src/utils/http.ts +++ b/packages/sdk/src/utils/http.ts @@ -1,5 +1,5 @@ -import type { ClawSwapConfig, ApiError } from '../types'; -import { NetworkError, mapApiError } from '../errors'; +import type { ClawSwapConfig } from '../types'; +import { ClawSwapError, NetworkError, TimeoutError, mapApiError } from '../errors'; /** * HTTP client with timeout and error handling @@ -46,18 +46,15 @@ export class HttpClient { clearTimeout(timeoutId); // Re-throw ClawSwapError instances without wrapping - if (error && typeof error === 'object' && 'code' in error) { + if (error instanceof ClawSwapError) { throw error; } if (error instanceof Error) { if (error.name === 'AbortError') { - throw new NetworkError('Request timed out', { - url, - timeoutMs: this.timeout, - }); + throw new TimeoutError('Request timed out', 'Increase the timeout option'); } - throw new NetworkError(error.message, { url, originalError: error }); + throw new NetworkError(error.message); } throw error; @@ -76,14 +73,16 @@ export class HttpClient { } private async handleErrorResponse(response: Response): Promise { - let errorData: Partial; + let errorData: unknown; try { - errorData = (await response.json()) as Partial; + errorData = await response.json(); } catch { errorData = { - code: 'UNKNOWN_ERROR', - message: response.statusText || 'Unknown error occurred', + error: { + code: 'NETWORK_ERROR', + message: response.statusText || 'Unknown error occurred', + }, }; } diff --git a/packages/sdk/src/utils/polling.ts b/packages/sdk/src/utils/polling.ts index 1dda3c4..171ea3e 100644 --- a/packages/sdk/src/utils/polling.ts +++ b/packages/sdk/src/utils/polling.ts @@ -13,19 +13,19 @@ export async function poll( const startTime = Date.now(); while (true) { + if (Date.now() - startTime > timeout) { + throw new TimeoutError( + 'Polling timed out', + 'Increase timeout or check network connectivity' + ); + } + const result = await fn(); if (!shouldContinue(result)) { return result; } - if (Date.now() - startTime > timeout) { - throw new TimeoutError('Polling timed out', { - timeoutMs: timeout, - elapsedMs: Date.now() - startTime, - }); - } - await sleep(interval); } } @@ -39,8 +39,8 @@ export function sleep(ms: number): Promise { /** * Check if swap is in terminal state - * Terminal statuses from Relay API: fulfilled, completed, failed, cancelled + * Terminal statuses: completed, failed */ export function isTerminalStatus(status: StatusResponse['status']): boolean { - return ['fulfilled', 'completed', 'failed', 'cancelled'].includes(status); + return ['completed', 'failed'].includes(status); } diff --git a/packages/sdk/tests/client.test.ts b/packages/sdk/tests/client.test.ts index e69fcee..f361d22 100644 --- a/packages/sdk/tests/client.test.ts +++ b/packages/sdk/tests/client.test.ts @@ -1,12 +1,14 @@ import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest'; import { ClawSwapClient } from '../src/client'; -import type { QuoteResponse, SwapResponse, StatusResponse, Chain, Token, EvmTransaction, ExecuteSwapResponse } from '../src/types'; -import { isEvmTransaction, isEvmSource, isSolanaSource } from '../src/types'; +import type { QuoteResponse, StatusResponse, Chain, Token, EvmTransaction, ExecuteSwapResponse } from '../src/types'; +import { isEvmSource, isSolanaSource } from '../src/types'; import { + ClawSwapError, InsufficientLiquidityError, - QuoteExpiredError, + NetworkError, PaymentRequiredError, TimeoutError, + UnsupportedChainError, } from '../src/errors'; describe('ClawSwapClient', () => { @@ -28,29 +30,32 @@ describe('ClawSwapClient', () => { describe('getQuote', () => { const validQuoteRequest = { - sourceChainId: 'solana', - sourceTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', - destinationChainId: 'base', - destinationTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + sourceChain: 'solana', + sourceToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', + destinationChain: 'base', + destinationToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', amount: '1000000', - senderAddress: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', - recipientAddress: '0x07150e919b4de5fd6a63de1f9384828396f25fdc', + userWallet: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', + recipient: '0x07150e919b4de5fd6a63de1f9384828396f25fdc', }; it('should return quote response successfully', async () => { const mockQuote: QuoteResponse = { - quoteId: 'quote-123', - sourceAmount: '1000000', - destinationAmount: '999000', + estimatedOutput: '999000', + estimatedOutputFormatted: '0.999', + estimatedTime: 300, fees: { - bridgeFeeUsd: 0.25, - x402FeeUsd: 0.50, - gasReimbursementEstimatedUsd: 0.002, - totalEstimatedFeeUsd: 0.752, + clawswap: '0.25', + relay: '0.03', + gas: '0.00 (sponsored)', }, - estimatedTimeSeconds: 300, - expiresAt: new Date(Date.now() + 30000).toISOString(), - expiresIn: 30, + route: { + sourceChain: 'solana', + sourceToken: { symbol: 'USDC', address: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', decimals: 6 }, + destinationChain: 'base', + destinationToken: { symbol: 'USDC', address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', decimals: 6 }, + }, + supported: true, }; mockFetch.mockResolvedValueOnce({ @@ -76,12 +81,12 @@ describe('ClawSwapClient', () => { it('should validate input parameters', async () => { await expect( client.getQuote({ - sourceChainId: '', - sourceTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', - destinationChainId: 'base', - destinationTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + sourceChain: '', + sourceToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', + destinationChain: 'base', + destinationToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', amount: '1000000', - }) + } as any) ).rejects.toThrow(); }); @@ -99,8 +104,7 @@ describe('ClawSwapClient', () => { ok: false, status: 400, json: async () => ({ - code: 'INSUFFICIENT_LIQUIDITY', - message: 'Not enough liquidity', + error: { code: 'INSUFFICIENT_LIQUIDITY', message: 'Not enough liquidity' }, }), }); @@ -112,41 +116,28 @@ describe('ClawSwapClient', () => { describe('executeSwap', () => { const validExecuteRequest = { - sourceChainId: 'solana', - sourceTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', - destinationChainId: 'base', - destinationTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + sourceChain: 'solana', + sourceToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', + destinationChain: 'base', + destinationToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', amount: '1000000', - senderAddress: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', - recipientAddress: '0x07150e919b4de5fd6a63de1f9384828396f25fdc', + userWallet: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', + recipient: '0x07150e919b4de5fd6a63de1f9384828396f25fdc', }; it('should execute swap successfully', async () => { - const mockExecuteResponse = { + const mockExecuteResponse: ExecuteSwapResponse = { + requestId: 'req-123', transaction: 'base64-encoded-transaction-data', - orderId: 'order-123', - isToken2022: false, - accounting: { - x402Fee: { - amountUsd: 0.50, - currency: 'USDC', - recipient: 'x402-treasury-address', - note: 'x402 payment for swap execution', - }, - gasReimbursement: { - amountRaw: '5000', - amountFormatted: '0.000005', - tokenMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', - recipient: 'recipient-address', - note: 'Gas reimbursement for Base transaction', - }, - bridgeFee: { - estimatedUsd: 0.25, - note: 'Relay bridge fee', - }, - sourceAmount: '1000000', - destinationAmount: '999000', + sourceChain: 'solana', + estimatedOutput: '999000', + estimatedTime: 300, + fees: { + clawswap: '0.25', + relay: '0.03', + gas: '0.00 (sponsored)', }, + instructions: 'Sign and submit to Solana RPC', }; mockFetch.mockResolvedValueOnce({ @@ -157,6 +148,7 @@ describe('ClawSwapClient', () => { const result = await client.executeSwap(validExecuteRequest); expect(result).toEqual(mockExecuteResponse); + expect(result.requestId).toBe('req-123'); expect(mockFetch).toHaveBeenCalledWith( 'https://api.test.clawswap.dev/api/swap/execute', expect.objectContaining({ @@ -170,19 +162,18 @@ describe('ClawSwapClient', () => { ok: false, status: 402, json: async () => ({ - code: 'PAYMENT_REQUIRED', - message: 'Payment required', + error: { code: 'PAYMENT_REQUIRED', message: 'Payment required' }, }), }); await expect(client.executeSwap(validExecuteRequest)).rejects.toThrow(PaymentRequiredError); }); - it('should require senderAddress', async () => { + it('should require userWallet', async () => { await expect( client.executeSwap({ ...validExecuteRequest, - senderAddress: '', + userWallet: '', }) ).rejects.toThrow(); }); @@ -191,17 +182,14 @@ describe('ClawSwapClient', () => { describe('getStatus', () => { it('should return swap status', async () => { const mockStatus: StatusResponse = { - orderId: 'order-123', - status: 'fulfilled', - sourceChainId: 'solana', - destinationChainId: 'base', - sourceAmount: '1000000', - destinationAmount: '999000', + requestId: 'req-123', + status: 'completed', + sourceChain: 'solana', + destinationChain: 'base', + outputAmount: '999000', sourceTxHash: '5J7Qstq6afbmW9mAW4GvKBZkLXhJ9J1UmZJpZEhcZcZz', - destinationTxHash: '0xabc123def456...', - explorerUrl: 'https://basescan.org/tx/0xabc123def456...', - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), + destinationTxHash: '0xabc123def456', + completedAt: new Date().toISOString(), }; mockFetch.mockResolvedValueOnce({ @@ -209,11 +197,11 @@ describe('ClawSwapClient', () => { json: async () => mockStatus, }); - const result = await client.getStatus('swap-123'); + const result = await client.getStatus('req-123'); expect(result).toEqual(mockStatus); expect(mockFetch).toHaveBeenCalledWith( - 'https://api.test.clawswap.dev/api/swap/swap-123/status', + 'https://api.test.clawswap.dev/api/swap/req-123/status', expect.any(Object) ); }); @@ -223,37 +211,28 @@ describe('ClawSwapClient', () => { it('should poll until completed', async () => { const mockStatuses: StatusResponse[] = [ { - orderId: 'swap-123', + requestId: 'req-123', status: 'pending', - sourceChainId: 'solana', - sourceAmount: '1000000', - destinationChainId: 'base', - destinationAmount: '999000', - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), + sourceChain: 'solana', + destinationChain: 'base', + outputAmount: '999000', }, { - orderId: 'swap-123', - status: 'created', - sourceChainId: 'solana', - sourceAmount: '1000000', - destinationChainId: 'base', - destinationAmount: '999000', - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), + requestId: 'req-123', + status: 'submitted', + sourceChain: 'solana', + destinationChain: 'base', + outputAmount: '999000', }, { - orderId: 'swap-123', + requestId: 'req-123', status: 'completed', - sourceChainId: 'solana', - sourceAmount: '1000000', - destinationChainId: 'base', - destinationAmount: '999000', + sourceChain: 'solana', + destinationChain: 'base', + outputAmount: '999000', sourceTxHash: '5J7Qstq6afbmW9mAW4GvKBZkLXhJ9J1UmZJpZEhcZcZz', - destinationTxHash: '0xabc123def456...', - explorerUrl: 'https://basescan.org/tx/0xabc123def456...', - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), + destinationTxHash: '0xabc123def456', + completedAt: new Date().toISOString(), }, ]; @@ -266,7 +245,7 @@ describe('ClawSwapClient', () => { }); }); - const result = await client.waitForSettlement('swap-123', { + const result = await client.waitForSettlement('req-123', { interval: 10, // Fast polling for tests }); @@ -278,19 +257,16 @@ describe('ClawSwapClient', () => { mockFetch.mockResolvedValue({ ok: true, json: async () => ({ - orderId: 'swap-123', + requestId: 'req-123', status: 'pending', - sourceChainId: 'solana', - sourceAmount: '1000000', - destinationChainId: 'base', - destinationAmount: '999000', - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), + sourceChain: 'solana', + destinationChain: 'base', + outputAmount: '999000', }), }); await expect( - client.waitForSettlement('swap-123', { + client.waitForSettlement('req-123', { timeout: 100, interval: 10, }) @@ -304,31 +280,26 @@ describe('ClawSwapClient', () => { .mockResolvedValueOnce({ ok: true, json: async () => ({ - orderId: 'swap-123', + requestId: 'req-123', status: 'pending', - sourceChainId: 'solana', - destinationChainId: 'base', - sourceAmount: '1000000', - destinationAmount: '999000', - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), + sourceChain: 'solana', + destinationChain: 'base', + outputAmount: '999000', }), }) .mockResolvedValueOnce({ ok: true, json: async () => ({ - orderId: 'swap-123', + requestId: 'req-123', status: 'completed', - sourceChainId: 'solana', - destinationChainId: 'base', - sourceAmount: '1000000', - destinationAmount: '999000', - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), + sourceChain: 'solana', + destinationChain: 'base', + outputAmount: '999000', + completedAt: new Date().toISOString(), }), }); - await client.waitForSettlement('swap-123', { + await client.waitForSettlement('req-123', { interval: 10, onStatusUpdate, }); @@ -365,6 +336,15 @@ describe('ClawSwapClient', () => { expect.any(Object) ); }); + + it('should throw NetworkError on malformed API response', async () => { + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ data: 'wrong shape' }), + }); + + await expect(client.getSupportedChains()).rejects.toThrow(NetworkError); + }); }); describe('getSupportedTokens', () => { @@ -392,34 +372,54 @@ describe('ClawSwapClient', () => { expect.any(Object) ); }); + + it('should reject path traversal in chainId', async () => { + await expect(client.getSupportedTokens('../admin')).rejects.toThrow(UnsupportedChainError); + await expect(client.getSupportedTokens('solana/../admin')).rejects.toThrow(UnsupportedChainError); + expect(mockFetch).not.toHaveBeenCalled(); + }); + + it('should throw NetworkError on malformed API response', async () => { + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ data: 'wrong shape' }), + }); + + await expect(client.getSupportedTokens('solana')).rejects.toThrow(NetworkError); + }); }); describe('timeout handling', () => { - it.skip('should timeout long requests', async () => { - mockFetch.mockImplementation( - () => - new Promise((resolve) => - setTimeout( - () => - resolve({ - ok: true, - json: async () => ({}), - }), - 10000 - ) - ) - ); + it('should throw TimeoutError on AbortError', async () => { + mockFetch.mockImplementation(() => { + const error = new DOMException('The operation was aborted', 'AbortError'); + return Promise.reject(error); + }); + + await expect(client.getQuote({ + sourceChain: 'solana', + sourceToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', + destinationChain: 'base', + destinationToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + amount: '1000000', + userWallet: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', + recipient: '0x07150e919b4de5fd6a63de1f9384828396f25fdc', + })).rejects.toThrow(TimeoutError); + }); + + it('should throw NetworkError for generic fetch failures', async () => { + mockFetch.mockRejectedValueOnce(new Error('ECONNREFUSED')); await expect(client.getQuote({ - sourceChainId: 'solana', - sourceTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', - destinationChainId: 'base', - destinationTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + sourceChain: 'solana', + sourceToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', + destinationChain: 'base', + destinationToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', amount: '1000000', - senderAddress: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', - recipientAddress: '0x07150e919b4de5fd6a63de1f9384828396f25fdc', - })).rejects.toThrow('Request timed out'); - }, 10000); + userWallet: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', + recipient: '0x07150e919b4de5fd6a63de1f9384828396f25fdc', + })).rejects.toThrow(NetworkError); + }); }); describe('getSwapFee', () => { @@ -430,21 +430,16 @@ describe('ClawSwapClient', () => { currency: 'USDC', network: 'solana', appliesTo: 'Solana-source swaps only', - description: 'x402 payment required per swap execution', - }, - gasReimbursement: { - estimatedUsd: '~0.001', - currency: 'USDC or USDT', - appliesTo: 'Solana-source swaps only', - description: 'Reimburses gas costs', + description: 'Fixed fee charged via x402 protocol.', }, + gasReimbursement: null, bridgeFee: { estimatedUsd: '~0.03–0.05', currency: 'Source token', appliesTo: 'All swaps', description: 'Relay bridge fee', }, - note: 'Solana-source: total cost = x402Fee + gasReimbursement + bridgeFee', + note: 'Solana-source: total cost = x402Fee + bridgeFee. EVM-source: total cost = bridgeFee + gas.', }; mockFetch.mockResolvedValueOnce({ @@ -456,7 +451,7 @@ describe('ClawSwapClient', () => { expect(result).toEqual(mockFee); expect(result.x402Fee.amountUsd).toBe(0.5); - expect(result.gasReimbursement.estimatedUsd).toBe('~0.001'); + expect(result.gasReimbursement).toBeNull(); expect(result.bridgeFee.estimatedUsd).toBe('~0.03–0.05'); expect(typeof result.note).toBe('string'); expect(mockFetch).toHaveBeenCalledWith( @@ -465,26 +460,27 @@ describe('ClawSwapClient', () => { ); }); - it('should propagate network errors', async () => { - mockFetch.mockRejectedValueOnce(new Error('Network error')); + it('should propagate network errors as NetworkError', async () => { + mockFetch.mockRejectedValueOnce(new Error('Connection refused')); - await expect(client.getSwapFee()).rejects.toThrow(); + await expect(client.getSwapFee()).rejects.toThrow(NetworkError); }); }); describe('executeSwap (Base → Solana)', () => { const baseToSolanaRequest = { - sourceChainId: 'base', - sourceTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', - destinationChainId: 'solana', - destinationTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', + sourceChain: 'base', + sourceToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + destinationChain: 'solana', + destinationToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', amount: '1000000', - senderAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', - recipientAddress: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', + userWallet: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', + recipient: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', }; it('should handle transactions array in response', async () => { - const mockResponse = { + const mockResponse: ExecuteSwapResponse = { + requestId: 'req-base-123', transactions: [ { to: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', @@ -501,15 +497,15 @@ describe('ClawSwapClient', () => { description: 'Bridge deposit', }, ], - orderId: '0xfedcba', - isToken2022: false, - accounting: { - x402Fee: { amountUsd: 0, currency: 'USDC', recipient: 'none', note: 'No x402 fee for EVM-source swaps' }, - gasReimbursement: null, - bridgeFee: { estimatedUsd: 0.037, note: 'Relay bridge fee' }, - sourceAmount: '1000000', - destinationAmount: '962766', + sourceChain: 'base', + estimatedOutput: '962766', + estimatedTime: 300, + fees: { + clawswap: '0', + relay: '0.037', + gas: 'paid by agent', }, + instructions: 'Sign and submit each transaction sequentially on Base', }; mockFetch.mockResolvedValueOnce({ @@ -524,25 +520,25 @@ describe('ClawSwapClient', () => { expect(result.transactions![0].description).toBe('Approve USDC spending'); expect(result.transactions![1].to).toBe('0xa5F565650890Fba1824Ee0F21EbBbF660a179934'); expect(result.transactions![1].chainId).toBe(8453); - expect(result.accounting.gasReimbursement).toBeNull(); - expect(result.accounting.x402Fee.amountUsd).toBe(0); - expect(result.isToken2022).toBe(false); + expect(result.fees.clawswap).toBe('0'); + expect(result.requestId).toBe('req-base-123'); }); it('should not require x402 payment for Base-source swaps', async () => { - const mockResponse = { + const mockResponse: ExecuteSwapResponse = { + requestId: 'req-base-456', transactions: [ { to: '0xabc', data: '0x123', value: '0', chainId: 8453 }, ], - orderId: '0xdef', - isToken2022: false, - accounting: { - x402Fee: { amountUsd: 0, currency: 'USDC', recipient: 'none', note: 'No x402 fee' }, - gasReimbursement: null, - bridgeFee: { estimatedUsd: 0.037, note: 'Relay bridge fee' }, - sourceAmount: '1000000', - destinationAmount: '962766', + sourceChain: 'base', + estimatedOutput: '962766', + estimatedTime: 300, + fees: { + clawswap: '0', + relay: '0.037', + gas: 'paid by agent', }, + instructions: 'Sign and submit on Base', }; mockFetch.mockResolvedValueOnce({ @@ -553,42 +549,23 @@ describe('ClawSwapClient', () => { const result = await client.executeSwap(baseToSolanaRequest); // Verify no 402 error was thrown (no x402 payment needed) - expect(result.orderId).toBe('0xdef'); - expect(result.accounting.x402Fee.amountUsd).toBe(0); - }); - }); - - describe('isEvmTransaction (deprecated)', () => { - it('should return true for EVM transaction objects', () => { - const evmTx: EvmTransaction = { - to: '0xa5F565650890Fba1824Ee0F21EbBbF660a179934', - data: '0xabcdef', - value: '0', - chainId: 8453, - }; - expect(isEvmTransaction(evmTx)).toBe(true); - }); - - it('should return false for strings', () => { - expect(isEvmTransaction('AQAAAAAAAAAAAAAAAACAAQAHDw...')).toBe(false); + expect(result.requestId).toBe('req-base-456'); + expect(result.fees.clawswap).toBe('0'); }); }); describe('isEvmSource / isSolanaSource', () => { it('should identify EVM source responses (transactions array)', () => { const evmResponse: ExecuteSwapResponse = { + requestId: 'req-123', transactions: [ { to: '0xabc', data: '0x123', value: '0', chainId: 8453 }, ], - orderId: 'order-123', - isToken2022: false, - accounting: { - x402Fee: { amountUsd: 0, currency: 'USDC', recipient: 'none', note: '' }, - gasReimbursement: null, - bridgeFee: { estimatedUsd: 0.037, note: '' }, - sourceAmount: '1000000', - destinationAmount: '962766', - }, + sourceChain: 'base', + estimatedOutput: '962766', + estimatedTime: 300, + fees: { clawswap: '0', relay: '0.037', gas: 'paid by agent' }, + instructions: 'Sign and submit on Base', }; expect(isEvmSource(evmResponse)).toBe(true); expect(isSolanaSource(evmResponse)).toBe(false); @@ -596,24 +573,36 @@ describe('ClawSwapClient', () => { it('should identify Solana source responses (transaction string)', () => { const solanaResponse: ExecuteSwapResponse = { + requestId: 'req-456', transaction: 'AQAAAAAAAAAAAAAAAACAAQAHDw...', - orderId: 'order-456', - isToken2022: false, - accounting: { - x402Fee: { amountUsd: 0.5, currency: 'USDC', recipient: 'treasury', note: '' }, - gasReimbursement: { amountRaw: '5000', amountFormatted: '0.000005', tokenMint: 'USDC', recipient: 'addr', note: '' }, - bridgeFee: { estimatedUsd: 0.037, note: '' }, - sourceAmount: '1000000', - destinationAmount: '962766', - }, + sourceChain: 'solana', + estimatedOutput: '999000', + estimatedTime: 300, + fees: { clawswap: '0.25', relay: '0.03', gas: '0.00 (sponsored)' }, + instructions: 'Sign and submit to Solana RPC', }; expect(isSolanaSource(solanaResponse)).toBe(true); expect(isEvmSource(solanaResponse)).toBe(false); }); + + it('should return false for both guards when both fields are present', () => { + const ambiguousResponse: ExecuteSwapResponse = { + requestId: 'req-789', + transaction: 'base64-data', + transactions: [{ to: '0xabc', data: '0x123', value: '0', chainId: 8453 }], + sourceChain: 'solana', + estimatedOutput: '999000', + estimatedTime: 300, + fees: { clawswap: '0.25', relay: '0.03', gas: '0.00' }, + instructions: 'Ambiguous', + }; + expect(isSolanaSource(ambiguousResponse)).toBe(false); + expect(isEvmSource(ambiguousResponse)).toBe(false); + }); }); describe('getSupportedPairs', () => { - it('should return all valid cross-chain pairs', async () => { + it('should return all valid cross-chain pairs with deduplicated token fetches', async () => { // Mock chains response const mockChains = { chains: [ @@ -635,17 +624,24 @@ describe('ClawSwapClient', () => { ], }; - mockFetch - .mockResolvedValueOnce({ ok: true, json: async () => mockChains }) - .mockResolvedValueOnce({ ok: true, json: async () => mockSolanaTokens }) - .mockResolvedValueOnce({ ok: true, json: async () => mockBaseTokens }) - .mockResolvedValueOnce({ ok: true, json: async () => mockBaseTokens }) - .mockResolvedValueOnce({ ok: true, json: async () => mockSolanaTokens }); + // With Promise.all optimization: 1 chains call + 2 token calls = 3 total + mockFetch.mockImplementation(async (url: string) => { + if (url.includes('/api/chains')) { + return { ok: true, json: async () => mockChains }; + } + if (url.includes('/api/tokens/solana')) { + return { ok: true, json: async () => mockSolanaTokens }; + } + if (url.includes('/api/tokens/base')) { + return { ok: true, json: async () => mockBaseTokens }; + } + return { ok: false, status: 404, json: async () => ({}) }; + }); const pairs = await client.getSupportedPairs(); expect(Array.isArray(pairs)).toBe(true); - expect(pairs.length).toBeGreaterThan(0); + expect(pairs.length).toBe(2); // solana->base USDC + base->solana USDC // Verify structure pairs.forEach((pair) => { @@ -653,10 +649,11 @@ describe('ClawSwapClient', () => { expect(pair).toHaveProperty('sourceToken'); expect(pair).toHaveProperty('destinationChain'); expect(pair).toHaveProperty('destinationToken'); - - // Verify no same-chain pairs expect(pair.sourceChain.id).not.toBe(pair.destinationChain.id); }); + + // Verify only 3 API calls (chains + solana tokens + base tokens) + expect(mockFetch).toHaveBeenCalledTimes(3); }); }); }); diff --git a/packages/sdk/tests/errors.test.ts b/packages/sdk/tests/errors.test.ts index b28cb08..237884b 100644 --- a/packages/sdk/tests/errors.test.ts +++ b/packages/sdk/tests/errors.test.ts @@ -1,13 +1,17 @@ import { describe, it, expect } from 'vitest'; import { ClawSwapError, + MissingFieldError, + UnsupportedChainError, + UnsupportedRouteError, + QuoteFailedError, InsufficientLiquidityError, AmountTooLowError, AmountTooHighError, - UnsupportedPairError, - QuoteExpiredError, + GasExceedsThresholdError, + RelayUnavailableError, PaymentRequiredError, - PaymentVerificationError, + RateLimitExceededError, NetworkError, TimeoutError, mapApiError, @@ -16,38 +20,75 @@ import { describe('Error Classes', () => { describe('ClawSwapError', () => { it('should create base error with code and message', () => { - const error = new ClawSwapError('UNKNOWN_ERROR', 'Test error'); + const error = new ClawSwapError('NETWORK_ERROR', 'Test error'); expect(error).toBeInstanceOf(Error); expect(error).toBeInstanceOf(ClawSwapError); - expect(error.code).toBe('UNKNOWN_ERROR'); + expect(error.code).toBe('NETWORK_ERROR'); expect(error.message).toBe('Test error'); expect(error.name).toBe('ClawSwapError'); }); - it('should include details', () => { - const details = { amount: '1000', minimum: '5000' }; - const error = new ClawSwapError('AMOUNT_TOO_LOW', 'Amount too low', details); + it('should include suggestion', () => { + const error = new ClawSwapError('AMOUNT_TOO_LOW', 'Amount too low', 'Try at least 1000 USDC'); + + expect(error.suggestion).toBe('Try at least 1000 USDC'); + }); + + it('should serialize to v2 JSON envelope', () => { + const error = new ClawSwapError('TIMEOUT', 'Request timed out', 'Increase timeout'); + const json = error.toJSON(); - expect(error.details).toEqual(details); + expect(json).toEqual({ + error: { + code: 'TIMEOUT', + message: 'Request timed out', + suggestion: 'Increase timeout', + }, + }); }); - it('should serialize to JSON', () => { - const error = new ClawSwapError('TIMEOUT', 'Request timed out', { timeoutMs: 30000 }); + it('should omit suggestion when undefined', () => { + const error = new ClawSwapError('TIMEOUT', 'Request timed out'); const json = error.toJSON(); expect(json).toEqual({ - code: 'TIMEOUT', - message: 'Request timed out', - details: { timeoutMs: 30000 }, + error: { + code: 'TIMEOUT', + message: 'Request timed out', + }, }); }); }); describe('Specific Error Classes', () => { + it('should create MissingFieldError', () => { + const error = new MissingFieldError(); + expect(error).toBeInstanceOf(ClawSwapError); + expect(error.code).toBe('MISSING_FIELD'); + expect(error.name).toBe('MissingFieldError'); + }); + + it('should create UnsupportedChainError', () => { + const error = new UnsupportedChainError(); + expect(error.code).toBe('UNSUPPORTED_CHAIN'); + expect(error.name).toBe('UnsupportedChainError'); + }); + + it('should create UnsupportedRouteError', () => { + const error = new UnsupportedRouteError(); + expect(error.code).toBe('UNSUPPORTED_ROUTE'); + expect(error.name).toBe('UnsupportedRouteError'); + }); + + it('should create QuoteFailedError', () => { + const error = new QuoteFailedError(); + expect(error.code).toBe('QUOTE_FAILED'); + expect(error.name).toBe('QuoteFailedError'); + }); + it('should create InsufficientLiquidityError', () => { const error = new InsufficientLiquidityError(); - expect(error).toBeInstanceOf(ClawSwapError); expect(error.code).toBe('INSUFFICIENT_LIQUIDITY'); expect(error.name).toBe('InsufficientLiquidityError'); @@ -56,52 +97,46 @@ describe('Error Classes', () => { it('should create AmountTooLowError with custom message', () => { const error = new AmountTooLowError('Minimum is 1000 USDC'); - expect(error.code).toBe('AMOUNT_TOO_LOW'); expect(error.message).toBe('Minimum is 1000 USDC'); }); it('should create AmountTooHighError', () => { const error = new AmountTooHighError(); - expect(error.code).toBe('AMOUNT_TOO_HIGH'); expect(error.name).toBe('AmountTooHighError'); }); - it('should create UnsupportedPairError', () => { - const error = new UnsupportedPairError(); - - expect(error.code).toBe('UNSUPPORTED_PAIR'); + it('should create GasExceedsThresholdError', () => { + const error = new GasExceedsThresholdError(); + expect(error.code).toBe('GAS_EXCEEDS_THRESHOLD'); + expect(error.name).toBe('GasExceedsThresholdError'); }); - it('should create QuoteExpiredError', () => { - const error = new QuoteExpiredError(); - - expect(error.code).toBe('QUOTE_EXPIRED'); - expect(error.message).toContain('expired'); + it('should create RelayUnavailableError', () => { + const error = new RelayUnavailableError(); + expect(error.code).toBe('RELAY_UNAVAILABLE'); + expect(error.name).toBe('RelayUnavailableError'); }); it('should create PaymentRequiredError', () => { const error = new PaymentRequiredError(); - expect(error.code).toBe('PAYMENT_REQUIRED'); }); - it('should create PaymentVerificationError', () => { - const error = new PaymentVerificationError(); - - expect(error.code).toBe('PAYMENT_VERIFICATION_FAILED'); + it('should create RateLimitExceededError', () => { + const error = new RateLimitExceededError(); + expect(error.code).toBe('RATE_LIMIT_EXCEEDED'); + expect(error.name).toBe('RateLimitExceededError'); }); it('should create NetworkError', () => { const error = new NetworkError(); - expect(error.code).toBe('NETWORK_ERROR'); }); it('should create TimeoutError', () => { const error = new TimeoutError(); - expect(error.code).toBe('TIMEOUT'); }); }); @@ -109,8 +144,7 @@ describe('Error Classes', () => { describe('mapApiError', () => { it('should map INSUFFICIENT_LIQUIDITY code', () => { const error = mapApiError(400, { - code: 'INSUFFICIENT_LIQUIDITY', - message: 'Not enough liquidity', + error: { code: 'INSUFFICIENT_LIQUIDITY', message: 'Not enough liquidity' }, }); expect(error).toBeInstanceOf(InsufficientLiquidityError); @@ -119,26 +153,23 @@ describe('Error Classes', () => { it('should map AMOUNT_TOO_LOW code', () => { const error = mapApiError(400, { - code: 'AMOUNT_TOO_LOW', - message: 'Amount below minimum', + error: { code: 'AMOUNT_TOO_LOW', message: 'Amount below minimum' }, }); expect(error).toBeInstanceOf(AmountTooLowError); }); - it('should map QUOTE_EXPIRED code', () => { + it('should map UNSUPPORTED_ROUTE code', () => { const error = mapApiError(400, { - code: 'QUOTE_EXPIRED', - message: 'Quote expired', + error: { code: 'UNSUPPORTED_ROUTE', message: 'Route not supported' }, }); - expect(error).toBeInstanceOf(QuoteExpiredError); + expect(error).toBeInstanceOf(UnsupportedRouteError); }); it('should map PAYMENT_REQUIRED code', () => { const error = mapApiError(402, { - code: 'PAYMENT_REQUIRED', - message: 'Payment required', + error: { code: 'PAYMENT_REQUIRED', message: 'Payment required' }, }); expect(error).toBeInstanceOf(PaymentRequiredError); @@ -146,56 +177,94 @@ describe('Error Classes', () => { it('should map TIMEOUT code', () => { const error = mapApiError(408, { - code: 'TIMEOUT', - message: 'Request timeout', + error: { code: 'TIMEOUT', message: 'Request timeout' }, }); expect(error).toBeInstanceOf(TimeoutError); }); - it('should handle unknown error codes', () => { + it('should map RATE_LIMIT_EXCEEDED code', () => { + const error = mapApiError(429, { + error: { code: 'RATE_LIMIT_EXCEEDED', message: 'Too many requests' }, + }); + + expect(error).toBeInstanceOf(RateLimitExceededError); + }); + + it('should handle unknown error codes gracefully', () => { const error = mapApiError(400, { - code: 'INVALID_CHAIN_ID' as any, - message: 'Invalid chain', + error: { code: 'SOME_NEW_CODE', message: 'Something new' }, }); expect(error).toBeInstanceOf(ClawSwapError); - expect(error.code).toBe('INVALID_CHAIN_ID'); + expect(error.code).toBe('SOME_NEW_CODE'); }); it('should fallback to 402 status code', () => { const error = mapApiError(402, { - message: 'Payment required', + error: { message: 'Payment required' }, }); expect(error).toBeInstanceOf(PaymentRequiredError); }); - it('should map 500+ status codes to SERVER_CONFIGURATION_ERROR', () => { + it('should fallback to 429 status code', () => { + const error = mapApiError(429, {}); + + expect(error).toBeInstanceOf(RateLimitExceededError); + }); + + it('should map 500+ status codes to RelayUnavailableError', () => { const error = mapApiError(500, { - message: 'Internal server error', + error: { message: 'Internal server error' }, }); - expect(error).toBeInstanceOf(ClawSwapError); - expect(error.code).toBe('SERVER_CONFIGURATION_ERROR'); + expect(error).toBeInstanceOf(RelayUnavailableError); + expect(error.code).toBe('RELAY_UNAVAILABLE'); }); - it('should default to UNKNOWN_ERROR', () => { + it('should default to NETWORK_ERROR for unknown status', () => { const error = mapApiError(400, {}); - expect(error.code).toBe('UNKNOWN_ERROR'); + expect(error.code).toBe('NETWORK_ERROR'); expect(error.message).toBe('Unknown error occurred'); }); - it('should preserve error details', () => { - const details = { minimumAmount: '1000', providedAmount: '500' }; + it('should preserve suggestion from error envelope', () => { const error = mapApiError(400, { - code: 'AMOUNT_TOO_LOW', - message: 'Amount too low', - details, + error: { + code: 'AMOUNT_TOO_LOW', + message: 'Amount too low', + suggestion: 'Try at least 1000 USDC', + }, }); - expect(error.details).toEqual(details); + expect(error.suggestion).toBe('Try at least 1000 USDC'); + }); + + it('should handle null errorData without throwing', () => { + const error = mapApiError(500, null); + expect(error).toBeInstanceOf(RelayUnavailableError); + }); + + it('should handle undefined errorData without throwing', () => { + const error = mapApiError(400, undefined); + expect(error).toBeInstanceOf(ClawSwapError); + expect(error.code).toBe('NETWORK_ERROR'); + }); + + it('should map 404 status code to UNSUPPORTED_ROUTE', () => { + const error = mapApiError(404, { + error: { message: 'Not found' }, + }); + expect(error.code).toBe('UNSUPPORTED_ROUTE'); + expect(error.message).toBe('Not found'); + }); + + it('should map 404 with no body to UNSUPPORTED_ROUTE', () => { + const error = mapApiError(404, {}); + expect(error.code).toBe('UNSUPPORTED_ROUTE'); + expect(error.message).toBe('Resource not found'); }); }); }); diff --git a/packages/sdk/tests/integration.test.ts b/packages/sdk/tests/integration.test.ts index 21969c8..c321e65 100644 --- a/packages/sdk/tests/integration.test.ts +++ b/packages/sdk/tests/integration.test.ts @@ -63,8 +63,7 @@ describe('Integration Tests', () => { }); describe('Quote Endpoint (Free)', () => { - it('should get a quote for SOL -> USDC on Base', async () => { - const chains = await client.getSupportedChains(); + it('should get a quote for USDC Solana -> USDC Base', async () => { const solanaTokens = await client.getSupportedTokens('solana'); const baseTokens = await client.getSupportedTokens('base'); @@ -78,39 +77,34 @@ describe('Integration Tests', () => { } const quote = await client.getQuote({ - sourceChainId: 'solana', - sourceTokenAddress: solanaUSDC.address, - destinationChainId: 'base', - destinationTokenAddress: baseUSDC.address, + sourceChain: 'solana', + sourceToken: solanaUSDC.address, + destinationChain: 'base', + destinationToken: baseUSDC.address, amount: '1000000', // 1 USDC (6 decimals) - senderAddress: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', - recipientAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', + userWallet: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', + recipient: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', }); - // Verify quote structure - expect(quote).toHaveProperty('id'); - expect(quote).toHaveProperty('sourceAmount'); - expect(quote).toHaveProperty('destinationAmount'); + // Verify v2 quote structure + expect(quote).toHaveProperty('estimatedOutput'); + expect(quote).toHaveProperty('estimatedOutputFormatted'); + expect(quote).toHaveProperty('estimatedTime'); expect(quote).toHaveProperty('fees'); - expect(quote.fees).toHaveProperty('totalFeeUsd'); - expect(quote).toHaveProperty('estimatedTimeSeconds'); - expect(quote).toHaveProperty('expiresAt'); - expect(quote).toHaveProperty('expiresIn'); - expect(quote).toHaveProperty('transactionData'); - - // Verify values - expect(quote.sourceAmount).toBe('1000000'); - expect(quote.expiresIn).toBeLessThanOrEqual(30); - expect(quote.expiresIn).toBeGreaterThan(0); - - // Verify destination amount is reasonable (accounting for fees) - const destAmount = parseFloat(quote.destinationAmount); - expect(destAmount).toBeGreaterThan(900000); // At least 0.9 USDC - expect(destAmount).toBeLessThanOrEqual(1000000); // At most 1 USDC + expect(quote.fees).toHaveProperty('clawswap'); + expect(quote.fees).toHaveProperty('relay'); + expect(quote.fees).toHaveProperty('gas'); + expect(quote).toHaveProperty('route'); + expect(quote).toHaveProperty('supported'); + + // Verify route structure + expect(quote.route).toHaveProperty('sourceChain'); + expect(quote.route).toHaveProperty('sourceToken'); + expect(quote.route).toHaveProperty('destinationChain'); + expect(quote.route).toHaveProperty('destinationToken'); }); it('should include fee breakdown in quote', async () => { - const chains = await client.getSupportedChains(); const solanaTokens = await client.getSupportedTokens('solana'); const baseTokens = await client.getSupportedTokens('base'); @@ -120,25 +114,20 @@ describe('Integration Tests', () => { if (!solanaUSDC || !baseUSDC) return; const quote = await client.getQuote({ - sourceChainId: 'solana', - sourceTokenAddress: solanaUSDC.address, - destinationChainId: 'base', - destinationTokenAddress: baseUSDC.address, + sourceChain: 'solana', + sourceToken: solanaUSDC.address, + destinationChain: 'base', + destinationToken: baseUSDC.address, amount: '1000000', - senderAddress: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', - recipientAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', + userWallet: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', + recipient: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', }); - // Verify fee structure (v2 API format) + // Verify v2 fee structure expect(quote).toHaveProperty('fees'); - expect(quote.fees).toHaveProperty('totalFeeUsd'); - expect(quote.fees).toHaveProperty('relayerFee'); - expect(quote.fees).toHaveProperty('gasSolLamports'); - - // Verify fee values are reasonable - const totalFee = parseFloat(quote.fees.totalFeeUsd); - expect(totalFee).toBeGreaterThan(0); - expect(totalFee).toBeLessThan(100); // Sanity check + expect(quote.fees).toHaveProperty('clawswap'); + expect(quote.fees).toHaveProperty('relay'); + expect(quote.fees).toHaveProperty('gas'); }); }); @@ -154,32 +143,33 @@ describe('Integration Tests', () => { const client = new ClawSwapClient({ fetch: fetchWithPayment }); const executeResponse = await client.executeSwap({ - sourceChainId: 'solana', - sourceTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', - destinationChainId: 'base', - destinationTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + sourceChain: 'solana', + sourceToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', + destinationChain: 'base', + destinationToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', amount: '1000000', - senderAddress: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', - recipientAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', + userWallet: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', + recipient: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', }); + expect(executeResponse).toHaveProperty('requestId'); expect(executeResponse).toHaveProperty('transaction'); - expect(executeResponse).toHaveProperty('metadata'); - expect(executeResponse.metadata).toHaveProperty('orderId'); - expect(executeResponse.metadata).toHaveProperty('paymentAmount'); - expect(executeResponse.metadata).toHaveProperty('gasLamports'); + expect(executeResponse).toHaveProperty('sourceChain'); + expect(executeResponse).toHaveProperty('estimatedOutput'); + expect(executeResponse).toHaveProperty('fees'); + expect(executeResponse).toHaveProperty('instructions'); */ }); it.skip('should poll swap status until completion', async () => { // This test requires a real swap ID from previous test /* - const result = await client.waitForSettlement('swap-id', { + const result = await client.waitForSettlement('request-id', { timeout: 300000, // 5 minutes interval: 5000, // Poll every 5 seconds }); - expect(['completed', 'failed', 'expired']).toContain(result.status); + expect(['completed', 'failed']).toContain(result.status); */ }); }); @@ -192,13 +182,13 @@ describe('Integration Tests', () => { it('should handle invalid quote parameters', async () => { await expect( client.getQuote({ - sourceChainId: 'solana', - sourceTokenAddress: 'invalid', - destinationChainId: 'base', - destinationTokenAddress: 'invalid', + sourceChain: 'solana', + sourceToken: 'invalid', + destinationChain: 'base', + destinationToken: 'invalid', amount: '1000000', - senderAddress: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', - recipientAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', + userWallet: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', + recipient: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', }) ).rejects.toThrow(); }); @@ -222,7 +212,6 @@ describe('Integration Tests', () => { }); it('should get quote quickly (< 3s)', async () => { - const chains = await client.getSupportedChains(); const solanaTokens = await client.getSupportedTokens('solana'); const baseTokens = await client.getSupportedTokens('base'); @@ -233,13 +222,13 @@ describe('Integration Tests', () => { const start = Date.now(); await client.getQuote({ - sourceChainId: 'solana', - sourceTokenAddress: solanaUSDC.address, - destinationChainId: 'base', - destinationTokenAddress: baseUSDC.address, + sourceChain: 'solana', + sourceToken: solanaUSDC.address, + destinationChain: 'base', + destinationToken: baseUSDC.address, amount: '1000000', - senderAddress: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', - recipientAddress: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', + userWallet: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', + recipient: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', }); const elapsed = Date.now() - start; diff --git a/packages/sdk/tests/polling.test.ts b/packages/sdk/tests/polling.test.ts index 7610272..4ae8bae 100644 --- a/packages/sdk/tests/polling.test.ts +++ b/packages/sdk/tests/polling.test.ts @@ -28,12 +28,12 @@ describe('Polling Utilities', () => { expect(isTerminalStatus('pending')).toBe(false); }); - it('should return false for bridging status', () => { - expect(isTerminalStatus('bridging')).toBe(false); + it('should return false for submitted status', () => { + expect(isTerminalStatus('submitted')).toBe(false); }); - it('should return false for settling status', () => { - expect(isTerminalStatus('settling')).toBe(false); + it('should return false for filling status', () => { + expect(isTerminalStatus('filling')).toBe(false); }); }); @@ -84,7 +84,7 @@ describe('Polling Utilities', () => { expect(result).toBe(2); }); - it('should include timeout details in error', async () => { + it('should include suggestion in timeout error', async () => { const mockFn = vi.fn(async () => 'pending'); try { @@ -93,8 +93,7 @@ describe('Polling Utilities', () => { } catch (error) { expect(error).toBeInstanceOf(TimeoutError); if (error instanceof TimeoutError) { - expect(error.details?.timeoutMs).toBe(50); - expect(error.details?.elapsedMs).toBeGreaterThanOrEqual(50); + expect(error.suggestion).toBe('Increase timeout or check network connectivity'); } } }); @@ -103,8 +102,8 @@ describe('Polling Utilities', () => { let status: StatusResponse['status'] = 'pending'; const mockFn = vi.fn(async () => { await sleep(5); - if (status === 'pending') status = 'bridging'; - else if (status === 'bridging') status = 'completed'; + if (status === 'pending') status = 'submitted'; + else if (status === 'submitted') status = 'completed'; return { status } as StatusResponse; }); diff --git a/packages/sdk/tests/schemas.test.ts b/packages/sdk/tests/schemas.test.ts index c498822..677934c 100644 --- a/packages/sdk/tests/schemas.test.ts +++ b/packages/sdk/tests/schemas.test.ts @@ -53,17 +53,27 @@ describe('Validation Schemas', () => { expect(() => amountSchema.parse('abc')).toThrow('Amount must be a positive number'); expect(() => amountSchema.parse('')).toThrow('Amount must be a positive number'); }); + + it('should reject scientific notation', () => { + expect(() => amountSchema.parse('1e308')).toThrow('Amount must be a positive number'); + expect(() => amountSchema.parse('1E10')).toThrow('Amount must be a positive number'); + expect(() => amountSchema.parse('1e-5')).toThrow('Amount must be a positive number'); + }); + + it('should reject Infinity', () => { + expect(() => amountSchema.parse('Infinity')).toThrow('Amount must be a positive number'); + }); }); describe('quoteRequestSchema', () => { const validQuoteRequest = { - sourceChainId: 'solana', - sourceTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', - destinationChainId: 'base', - destinationTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + sourceChain: 'solana', + sourceToken: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', + destinationChain: 'base', + destinationToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', amount: '1000000', - senderAddress: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', - recipientAddress: '0x07150e919b4de5fd6a63de1f9384828396f25fdc', + userWallet: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri', + recipient: '0x07150e919b4de5fd6a63de1f9384828396f25fdc', }; it('should validate complete quote request', () => { @@ -71,23 +81,23 @@ describe('Validation Schemas', () => { expect(result).toEqual(validQuoteRequest); }); - it('should reject missing sourceChainId', () => { - const { sourceChainId, ...incomplete } = validQuoteRequest; + it('should reject missing sourceChain', () => { + const { sourceChain, ...incomplete } = validQuoteRequest; expect(() => quoteRequestSchema.parse(incomplete)).toThrow(); }); - it('should reject missing sourceTokenAddress', () => { - const { sourceTokenAddress, ...incomplete } = validQuoteRequest; + it('should reject missing sourceToken', () => { + const { sourceToken, ...incomplete } = validQuoteRequest; expect(() => quoteRequestSchema.parse(incomplete)).toThrow(); }); - it('should reject missing destinationChainId', () => { - const { destinationChainId, ...incomplete } = validQuoteRequest; + it('should reject missing destinationChain', () => { + const { destinationChain, ...incomplete } = validQuoteRequest; expect(() => quoteRequestSchema.parse(incomplete)).toThrow(); }); - it('should reject missing destinationTokenAddress', () => { - const { destinationTokenAddress, ...incomplete } = validQuoteRequest; + it('should reject missing destinationToken', () => { + const { destinationToken, ...incomplete } = validQuoteRequest; expect(() => quoteRequestSchema.parse(incomplete)).toThrow(); }); @@ -100,23 +110,23 @@ describe('Validation Schemas', () => { expect(() => quoteRequestSchema.parse({ ...validQuoteRequest, - sourceChainId: '', + sourceChain: '', }) ).toThrow(); }); }); describe('statusRequestSchema', () => { - it('should validate order ID', () => { - const result = statusRequestSchema.parse({ orderId: 'order-123' }); - expect(result.orderId).toBe('order-123'); + it('should validate request ID', () => { + const result = statusRequestSchema.parse({ requestId: 'req-123' }); + expect(result.requestId).toBe('req-123'); }); - it('should reject empty order ID', () => { - expect(() => statusRequestSchema.parse({ orderId: '' })).toThrow(); + it('should reject empty request ID', () => { + expect(() => statusRequestSchema.parse({ requestId: '' })).toThrow(); }); - it('should reject missing order ID', () => { + it('should reject missing request ID', () => { expect(() => statusRequestSchema.parse({})).toThrow(); }); }); From ad1ed8e34c63dfdc4714eb99e435734d67af157f Mon Sep 17 00:00:00 2001 From: WarTech9 Date: Thu, 26 Feb 2026 00:00:40 -0500 Subject: [PATCH 3/6] freeze lockfile --- .github/workflows/e2e-examples.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-examples.yml b/.github/workflows/e2e-examples.yml index 59f372c..53644db 100644 --- a/.github/workflows/e2e-examples.yml +++ b/.github/workflows/e2e-examples.yml @@ -26,7 +26,7 @@ jobs: cache: 'pnpm' - name: Install dependencies - run: pnpm install + run: pnpm install --frozen-lockfile - name: Build all packages run: pnpm build From 33942104e1ae6b38e84f0911334f101af4305269 Mon Sep 17 00:00:00 2001 From: WarTech9 Date: Thu, 26 Feb 2026 00:14:57 -0500 Subject: [PATCH 4/6] Fix references in browser examples to use new fields. --- examples/browser-wagmi/src/App.tsx | 8 +-- .../browser-wagmi/src/components/SwapForm.tsx | 45 ++++++------ .../src/components/SwapProgress.tsx | 32 ++++----- .../browser-wagmi/src/hooks/useClawSwap.ts | 4 +- examples/browser/src/App.tsx | 13 ++-- examples/browser/src/components/QuoteForm.tsx | 56 +++++++-------- .../browser/src/components/StatusPanel.tsx | 33 ++++----- .../browser/src/components/SwapButton.tsx | 72 ++++++++----------- 8 files changed, 116 insertions(+), 147 deletions(-) diff --git a/examples/browser-wagmi/src/App.tsx b/examples/browser-wagmi/src/App.tsx index c85ab75..8f44a05 100644 --- a/examples/browser-wagmi/src/App.tsx +++ b/examples/browser-wagmi/src/App.tsx @@ -9,7 +9,7 @@ import './styles.css'; export function App() { const { isConnected } = useAccount(); const phantom = usePhantomWallet(); - const [orderId, setOrderId] = useState(null); + const [requestId, setRequestId] = useState(null); const anyConnected = isConnected || phantom.connected; @@ -48,13 +48,13 @@ export function App() { <>

Swap

- +
- {orderId && ( + {requestId && (

Settlement Status

- +
)} diff --git a/examples/browser-wagmi/src/components/SwapForm.tsx b/examples/browser-wagmi/src/components/SwapForm.tsx index d986665..bce1d03 100644 --- a/examples/browser-wagmi/src/components/SwapForm.tsx +++ b/examples/browser-wagmi/src/components/SwapForm.tsx @@ -10,7 +10,7 @@ interface PhantomState { } interface Props { - onSwapInitiated: (orderId: string) => void; + onSwapInitiated: (requestId: string) => void; phantom?: PhantomState; } @@ -69,13 +69,13 @@ export function SwapForm({ onSwapInitiated, phantom }: Props) { try { const result = await getQuote({ - sourceChainId: sourceChain, - sourceTokenAddress: sourceToken, - destinationChainId: destChain, - destinationTokenAddress: destToken, + sourceChain, + sourceToken, + destinationChain: destChain, + destinationToken: destToken, amount, - senderAddress: address, - recipientAddress, + userWallet: address, + recipient: recipientAddress, }); setQuote(result); } finally { @@ -93,17 +93,17 @@ export function SwapForm({ onSwapInitiated, phantom }: Props) { try { const response = await executeAndSign({ - sourceChainId: sourceChain, - sourceTokenAddress: sourceToken, - destinationChainId: destChain, - destinationTokenAddress: destToken, - amount: quote.sourceAmount, - senderAddress: address, - recipientAddress, + sourceChain, + sourceToken, + destinationChain: destChain, + destinationToken: destToken, + amount, + userWallet: address, + recipient: recipientAddress, }); setSigningStatus(''); - onSwapInitiated(response.orderId); + onSwapInitiated(response.requestId); } catch { setSigningStatus(''); } finally { @@ -112,7 +112,7 @@ export function SwapForm({ onSwapInitiated, phantom }: Props) { }; const canQuote = sourceChain && destChain && sourceToken && destToken && amount && address && recipientAddress; - const isExpired = quote ? quote.expiresIn <= 0 : false; + const canSwap = !!quote; return (
@@ -195,18 +195,17 @@ export function SwapForm({ onSwapInitiated, phantom }: Props) { {quote && (

Quote

-
You send:{quote.sourceAmount}
-
You receive:{quote.destinationAmount}
-
Fee:${quote.fees.totalEstimatedFeeUsd.toFixed(2)}
-
Est. time:{quote.estimatedTimeSeconds}s
-
Expires in:{quote.expiresIn}s
+
You send:{amount} (smallest units)
+
You receive:{quote.estimatedOutputFormatted}
+
Fees:ClawSwap: {quote.fees.clawswap} | Relay: {quote.fees.relay} | Gas: {quote.fees.gas}
+
Est. time:{quote.estimatedTime}s
)} diff --git a/examples/browser-wagmi/src/components/SwapProgress.tsx b/examples/browser-wagmi/src/components/SwapProgress.tsx index 2901783..97b9acf 100644 --- a/examples/browser-wagmi/src/components/SwapProgress.tsx +++ b/examples/browser-wagmi/src/components/SwapProgress.tsx @@ -9,11 +9,11 @@ interface PhantomState { } interface Props { - orderId: string; + requestId: string; phantom?: PhantomState; } -export function SwapProgress({ orderId, phantom }: Props) { +export function SwapProgress({ requestId, phantom }: Props) { const { waitForSettlement } = useClawSwap(phantom); const [status, setStatus] = useState(null); const [settled, setSettled] = useState(false); @@ -24,7 +24,7 @@ export function SwapProgress({ orderId, phantom }: Props) { async function poll() { try { - const result = await waitForSettlement(orderId, (s) => { + const result = await waitForSettlement(requestId, (s) => { if (!cancelled) setStatus(s); }); if (!cancelled) { @@ -41,7 +41,7 @@ export function SwapProgress({ orderId, phantom }: Props) { poll(); return () => { cancelled = true; }; - }, [orderId, waitForSettlement]); + }, [requestId, waitForSettlement]); if (error) { return
{error}
; @@ -51,7 +51,7 @@ export function SwapProgress({ orderId, phantom }: Props) { return
Loading swap status...
; } - const isSuccess = status.status === 'completed' || status.status === 'fulfilled'; + const isSuccess = status.status === 'completed'; const isFailed = status.status === 'failed'; return ( @@ -62,16 +62,16 @@ export function SwapProgress({ orderId, phantom }: Props) {
- Order ID: - {status.orderId} + Request ID: + {status.requestId}
Source: - {status.sourceChainId} - {status.sourceAmount} + {status.sourceChain}
Destination: - {status.destinationChainId} - {status.destinationAmount} + {status.destinationChain}: {status.outputAmount}
{status.sourceTxHash && (
@@ -82,26 +82,20 @@ export function SwapProgress({ orderId, phantom }: Props) { {status.destinationTxHash && (
Dest TX: - {status.explorerUrl ? ( - - {status.destinationTxHash.slice(0, 10)}...{status.destinationTxHash.slice(-8)} - - ) : ( - {status.destinationTxHash.slice(0, 10)}...{status.destinationTxHash.slice(-8)} - )} + {status.destinationTxHash.slice(0, 10)}...{status.destinationTxHash.slice(-8)}
)}
{isSuccess && (
- Swap completed! Received {status.destinationAmount} tokens. + Swap completed! Received {status.outputAmount} tokens.
)} - {isFailed && status.failureReason && ( + {isFailed && (
- Swap failed: {status.failureReason} + Swap failed.
)} diff --git a/examples/browser-wagmi/src/hooks/useClawSwap.ts b/examples/browser-wagmi/src/hooks/useClawSwap.ts index 4851fc6..b36d84b 100644 --- a/examples/browser-wagmi/src/hooks/useClawSwap.ts +++ b/examples/browser-wagmi/src/hooks/useClawSwap.ts @@ -202,10 +202,10 @@ export function useClawSwap(phantom?: PhantomState) { }, [walletClient, publicClient, client, phantom]); const waitForSettlement = useCallback(async ( - orderId: string, + requestId: string, onStatusUpdate?: (status: StatusResponse) => void, ): Promise => { - return client.waitForSettlement(orderId, { + return client.waitForSettlement(requestId, { timeout: 300_000, interval: 3000, onStatusUpdate, diff --git a/examples/browser/src/App.tsx b/examples/browser/src/App.tsx index e4b2a69..02fc577 100644 --- a/examples/browser/src/App.tsx +++ b/examples/browser/src/App.tsx @@ -82,12 +82,13 @@ export function App() {

Quote Details

-
- Quote ID: - {quote.quoteId} -
You send: - {quote.sourceAmount} + {amount} (smallest units)
You receive: - {quote.destinationAmount} + {quote.estimatedOutputFormatted}
- Total fee: - ${quote.fees.totalEstimatedFeeUsd.toFixed(2)} + Fees: + ClawSwap: {quote.fees.clawswap} | Relay: {quote.fees.relay} | Gas: {quote.fees.gas}
Estimated time: - {quote.estimatedTimeSeconds}s -
-
- Expires in: - {quote.expiresIn}s + {quote.estimatedTime}s
diff --git a/examples/browser/src/components/StatusPanel.tsx b/examples/browser/src/components/StatusPanel.tsx index 5591974..8bf3707 100644 --- a/examples/browser/src/components/StatusPanel.tsx +++ b/examples/browser/src/components/StatusPanel.tsx @@ -29,7 +29,7 @@ export function StatusPanel({ client, swapId }: Props) { setStatus(result); // Stop polling on terminal status - if (['completed', 'fulfilled', 'failed', 'cancelled'].includes(result.status)) { + if (['completed', 'failed'].includes(result.status)) { setPolling(false); } } catch (err) { @@ -46,10 +46,9 @@ export function StatusPanel({ client, swapId }: Props) { return
Loading status...
; } - const isSuccess = status.status === 'completed' || status.status === 'fulfilled'; + const isSuccess = status.status === 'completed'; const statusClass = isSuccess ? 'success' : status.status === 'failed' ? 'error' : - status.status === 'cancelled' ? 'warning' : 'info'; return ( @@ -60,16 +59,16 @@ export function StatusPanel({ client, swapId }: Props) {
- Order ID: - {status.orderId} + Request ID: + {status.requestId}
Source: - {status.sourceChainId}: {status.sourceAmount} + {status.sourceChain}
Destination: - {status.destinationChainId}: {status.destinationAmount} + {status.destinationChain}: {status.outputAmount}
{status.sourceTxHash && (
@@ -80,32 +79,26 @@ export function StatusPanel({ client, swapId }: Props) { {status.destinationTxHash && (
Destination TX: - {status.explorerUrl ? ( - - {status.destinationTxHash.slice(0, 10)}...{status.destinationTxHash.slice(-8)} - - ) : ( - {status.destinationTxHash.slice(0, 10)}...{status.destinationTxHash.slice(-8)} - )} + {status.destinationTxHash.slice(0, 10)}...{status.destinationTxHash.slice(-8)}
)} - {status.estimatedCompletionTime && ( + {status.completedAt && (
- Estimated completion: - {new Date(status.estimatedCompletionTime).toLocaleTimeString()} + Completed at: + {new Date(status.completedAt).toLocaleTimeString()}
)}
{isSuccess && (
- Swap completed successfully! You received {status.destinationAmount} tokens. + Swap completed successfully! You received {status.outputAmount} tokens.
)} - {status.status === 'failed' && status.failureReason && ( + {status.status === 'failed' && (
- Swap failed: {status.failureReason} + Swap failed.
)} diff --git a/examples/browser/src/components/SwapButton.tsx b/examples/browser/src/components/SwapButton.tsx index 084209d..8f7bc43 100644 --- a/examples/browser/src/components/SwapButton.tsx +++ b/examples/browser/src/components/SwapButton.tsx @@ -7,17 +7,18 @@ const SOLANA_RPC_URL = import.meta.env.VITE_SOLANA_RPC_URL || 'https://api.mainn interface Props { client: ClawSwapClient; quote: QuoteResponse; - sourceChainId: string; - sourceTokenAddress: string; - destinationChainId: string; - destinationTokenAddress: string; - senderAddress: string; - destinationAddress: string; + sourceChain: string; + sourceToken: string; + destinationChain: string; + destinationToken: string; + userWallet: string; + recipient: string; + amount: string; walletClient: WalletClient | null; publicClient: PublicClient | null; ensureBaseChain: () => Promise; solanaConnected: boolean; - onSwapInitiated?: (orderId: string) => void; + onSwapInitiated?: (requestId: string) => void; } interface TxResult { @@ -29,12 +30,13 @@ interface TxResult { export function SwapButton({ client, quote, - sourceChainId, - sourceTokenAddress, - destinationChainId, - destinationTokenAddress, - senderAddress, - destinationAddress, + sourceChain, + sourceToken, + destinationChain, + destinationToken, + userWallet, + recipient, + amount, walletClient, publicClient, ensureBaseChain, @@ -54,14 +56,13 @@ export function SwapButton({ try { const executeResponse = await client.executeSwap({ - sourceChainId, - sourceTokenAddress, - destinationChainId, - destinationTokenAddress, - amount: quote.sourceAmount, - senderAddress, - recipientAddress: destinationAddress, - slippageTolerance: 0.01, + sourceChain, + sourceToken, + destinationChain, + destinationToken, + amount, + userWallet, + recipient, }); console.log('Swap response:', executeResponse); @@ -142,7 +143,7 @@ export function SwapButton({ setStatus('Transaction confirmed! Waiting for cross-chain settlement...'); } - onSwapInitiated?.(executeResponse.orderId); + onSwapInitiated?.(executeResponse.requestId); } catch (err) { console.error('Swap failed:', err); setError(err instanceof Error ? err.message : 'Failed to execute swap'); @@ -151,46 +152,33 @@ export function SwapButton({ } }; - const expiresInSeconds = quote.expiresIn; - const isExpired = expiresInSeconds <= 0; - return (
-
- You send: - {quote.sourceAmount} -
You receive: - {quote.destinationAmount} + {quote.estimatedOutputFormatted}
- Destination: - {destinationAddress.slice(0, 10)}...{destinationAddress.slice(-6)} + Recipient: + {recipient.slice(0, 10)}...{recipient.slice(-6)}
- Estimated fee: - ${quote.fees.totalEstimatedFeeUsd.toFixed(2)} + Estimated time: + {quote.estimatedTime}s
{status &&
{status}
} - {isExpired && ( -

- This quote has expired. Please get a new quote. -

- )} - {txResults.length > 0 && (

Transactions

From 60d06b9fb5f87b42ecf93db829d086637a33bcb9 Mon Sep 17 00:00:00 2001 From: WarTech9 Date: Thu, 26 Feb 2026 01:38:35 -0500 Subject: [PATCH 5/6] Fix references in examples --- examples/node-cli/e2e/api-direct.ts | 121 ++++++++++------------ examples/node-cli/e2e/sdk-integration.ts | 122 +++++++++++------------ 2 files changed, 112 insertions(+), 131 deletions(-) diff --git a/examples/node-cli/e2e/api-direct.ts b/examples/node-cli/e2e/api-direct.ts index cb13be0..8a4fe8c 100644 --- a/examples/node-cli/e2e/api-direct.ts +++ b/examples/node-cli/e2e/api-direct.ts @@ -140,50 +140,43 @@ async function testQuoteForPair( sourceTokenAddress: string, destinationTokenAddress: string, pairLabel: string, -): Promise<{ quoteId: string; sourceAmount: string }> { +): Promise { section(`Section 2 — Quote: ${pairLabel} (free, no payment)`); const quoteRequest = { - sourceChainId: 'solana', - sourceTokenAddress, - destinationChainId: 'base', - destinationTokenAddress, + sourceChain: 'solana', + sourceToken: sourceTokenAddress, + destinationChain: 'base', + destinationToken: destinationTokenAddress, amount: SWAP_AMOUNT, - senderAddress: TEST_SENDER, - recipientAddress: RECIPIENT_ADDRESS, + userWallet: TEST_SENDER, + recipient: RECIPIENT_ADDRESS, }; const quote = await apiPost('/api/swap/quote', quoteRequest); - assert(typeof quote.quoteId === 'string' && quote.quoteId.length > 0, 'Quote has quoteId'); - assert(typeof quote.sourceAmount === 'string', 'Quote has sourceAmount (string)'); - assert(typeof quote.destinationAmount === 'string', 'Quote has destinationAmount (string)'); + assert(typeof quote.estimatedOutput === 'string', 'Quote has estimatedOutput (string)'); + assert(typeof quote.estimatedOutputFormatted === 'string', 'Quote has estimatedOutputFormatted (string)'); + assert(typeof quote.estimatedTime === 'number', 'Quote has estimatedTime (number)'); assert(typeof quote.fees === 'object', 'Quote has fees object'); - assert(typeof quote.fees.totalEstimatedFeeUsd === 'number', 'fees.totalEstimatedFeeUsd is a number'); - assert(typeof quote.fees.bridgeFeeUsd === 'number', 'fees.bridgeFeeUsd is a number'); - assert(typeof quote.fees.x402FeeUsd === 'number', 'fees.x402FeeUsd is a number'); - assert(typeof quote.fees.gasReimbursementEstimatedUsd === 'number', 'fees.gasReimbursementEstimatedUsd is a number'); - assert(typeof quote.estimatedTimeSeconds === 'number', 'Quote has estimatedTimeSeconds'); - assert(typeof quote.expiresIn === 'number', 'Quote has expiresIn'); - assert(typeof quote.expiresAt === 'string', 'Quote has expiresAt (ISO string)'); - - const destAmount = parseFloat(quote.destinationAmount); - const inputAmount = Number(SWAP_AMOUNT); - assert(destAmount > inputAmount * 0.9, `Destination amount > 90% of input (got ${destAmount}, input ${inputAmount})`); - assert(destAmount <= inputAmount, `Destination amount ≤ input amount (got ${destAmount})`); - assert(quote.fees.totalEstimatedFeeUsd > 0, `Total fee > 0 (got ${quote.fees.totalEstimatedFeeUsd})`); + assert(typeof quote.fees.clawswap === 'string', 'fees.clawswap is a string'); + assert(typeof quote.fees.relay === 'string', 'fees.relay is a string'); + assert(typeof quote.fees.gas === 'string', 'fees.gas is a string'); + assert(typeof quote.route === 'object', 'Quote has route object'); + assert(typeof quote.supported === 'boolean', 'Quote has supported (boolean)'); - console.log(`\n Quote ID: ${quote.quoteId}`); - console.log(` Destination amount: ${destAmount / 1e6}`); - console.log(` Total Fee: $${quote.fees.totalEstimatedFeeUsd}`); - console.log(` Expires in: ${quote.expiresIn}s`); + const destAmount = parseFloat(quote.estimatedOutput); + const inputAmount = Number(SWAP_AMOUNT); + assert(destAmount > inputAmount * 0.9, `Estimated output > 90% of input (got ${destAmount}, input ${inputAmount})`); - return { quoteId: quote.quoteId, sourceAmount: quote.sourceAmount }; + console.log(`\n Estimated output: ${quote.estimatedOutputFormatted}`); + console.log(` Fees — ClawSwap: ${quote.fees.clawswap} | Relay: ${quote.fees.relay} | Gas: ${quote.fees.gas}`); + console.log(` Estimated time: ${quote.estimatedTime}s`); } // ─── Section 3: Execute (requires SOLANA_PRIVATE_KEY) ─────────────────────── -async function testExecute(): Promise<{ transaction: string; orderId: string } | null> { +async function testExecute(): Promise<{ transaction: string; requestId: string } | null> { section('Section 3 — Execute (requires x402 payment)'); if (!SOLANA_PRIVATE_KEY) { @@ -220,63 +213,59 @@ async function testExecute(): Promise<{ transaction: string; orderId: string } | console.log(` Pair: ${execPairLabel}`); const executeRequest = { - sourceChainId: 'solana', - sourceTokenAddress: EXEC_SOURCE_TOKEN, - destinationChainId: 'base', - destinationTokenAddress: EXEC_DEST_TOKEN, + sourceChain: 'solana', + sourceToken: EXEC_SOURCE_TOKEN, + destinationChain: 'base', + destinationToken: EXEC_DEST_TOKEN, amount: SWAP_AMOUNT, - senderAddress, - recipientAddress: RECIPIENT_ADDRESS, + userWallet: senderAddress, + recipient: RECIPIENT_ADDRESS, }; console.log(' Sending execute request (x402 payment will be deducted)...'); const response = await apiPost('/api/swap/execute', executeRequest, fetchWithPayment); + assert(typeof response.requestId === 'string', 'Response has requestId (string)'); assert(typeof response.transaction === 'string', 'Response has transaction (base64 string)'); assert(response.transaction.length > 0, 'Transaction is non-empty'); - assert(typeof response.orderId === 'string', 'Response has orderId (string)'); - assert(typeof response.isToken2022 === 'boolean', 'Response has isToken2022 (boolean)'); - assert(typeof response.accounting === 'object', 'Response has accounting object'); - assert(typeof response.accounting.x402Fee.amountUsd === 'number', 'accounting.x402Fee.amountUsd is a number'); - if (response.accounting.gasReimbursement) { - assert(typeof response.accounting.gasReimbursement.amountRaw === 'string', 'accounting.gasReimbursement.amountRaw is a string'); - assert(typeof response.accounting.gasReimbursement.amountFormatted === 'string', 'accounting.gasReimbursement.amountFormatted is a string'); - } - assert(typeof response.accounting.bridgeFee.estimatedUsd === 'number', 'accounting.bridgeFee.estimatedUsd is a number'); - - console.log(`\n Order ID: ${response.orderId}`); - console.log(` x402 Fee: $${response.accounting.x402Fee.amountUsd}`); - console.log(` Gas Reimbursement: ${response.accounting.gasReimbursement?.amountFormatted ?? 'N/A'}`); + assert(typeof response.sourceChain === 'string', 'Response has sourceChain'); + assert(typeof response.estimatedOutput === 'string', 'Response has estimatedOutput'); + assert(typeof response.estimatedTime === 'number', 'Response has estimatedTime'); + assert(typeof response.fees === 'object', 'Response has fees object'); + assert(typeof response.fees.clawswap === 'string', 'fees.clawswap is a string'); + assert(typeof response.instructions === 'string', 'Response has instructions'); + + console.log(`\n Request ID: ${response.requestId}`); + console.log(` Estimated output: ${response.estimatedOutput}`); + console.log(` Fees — ClawSwap: ${response.fees.clawswap} | Relay: ${response.fees.relay} | Gas: ${response.fees.gas}`); console.log(` Transaction size: ${response.transaction.length} base64 chars`); - return { transaction: response.transaction, orderId: response.orderId }; + return { transaction: response.transaction, requestId: response.requestId }; } // ─── Section 4: Status ─────────────────────────────────────────────────────── -async function testStatus(orderId: string): Promise { +async function testStatus(requestId: string): Promise { section('Section 4 — Status check (free)'); - const response = await apiGet(`/api/swap/${orderId}/status`); + const response = await apiGet(`/api/swap/${requestId}/status`); - const id = response.swapId ?? response.orderId; - assert(typeof id === 'string', 'Status has swapId or orderId'); + assert(typeof response.requestId === 'string', 'Status has requestId'); assert(typeof response.status === 'string', 'Status has status field'); - assert(typeof response.sourceChainId === 'string', 'Status has sourceChainId'); - assert(typeof response.destinationChainId === 'string', 'Status has destinationChainId'); - assert(typeof response.sourceAmount === 'string', 'Status has sourceAmount'); - assert(typeof response.destinationAmount === 'string', 'Status has destinationAmount'); + assert(typeof response.sourceChain === 'string', 'Status has sourceChain'); + assert(typeof response.destinationChain === 'string', 'Status has destinationChain'); + assert(typeof response.outputAmount === 'string', 'Status has outputAmount'); - const validStatuses = ['pending', 'created', 'bridging', 'settling', 'fulfilled', 'completed', 'failed', 'cancelled']; + const validStatuses = ['pending', 'submitted', 'filling', 'completed', 'failed']; assert(validStatuses.includes(response.status), `Status "${response.status}" is a known value`); - console.log(`\n Order: ${id}`); + console.log(`\n Request: ${response.requestId}`); console.log(` Status: ${response.status}`); } // ─── Section 5: Sign & Submit ──────────────────────────────────────────────── -async function testSignAndSubmit(transaction: string, orderId: string): Promise { +async function testSignAndSubmit(transaction: string, requestId: string): Promise { section('Section 5 — Sign & Submit Solana Transaction'); if (SKIP_SUBMIT) { @@ -316,13 +305,13 @@ async function testSignAndSubmit(transaction: string, orderId: string): Promise< assert(!confirmation.value.err, 'Transaction confirmed on Solana'); // Poll status until terminal - console.log(`\n Polling status for order ${orderId}...`); - const terminal = ['fulfilled', 'completed', 'failed', 'cancelled']; + console.log(`\n Polling status for request ${requestId}...`); + const terminal = ['completed', 'failed']; let finalStatus: string = 'pending'; const timeout = Date.now() + 300_000; // 5 min while (Date.now() < timeout) { - const status = await apiGet(`/api/swap/${orderId}/status`); + const status = await apiGet(`/api/swap/${requestId}/status`); finalStatus = status.status; console.log(` Status: ${finalStatus}`); if (terminal.includes(finalStatus)) break; @@ -330,7 +319,7 @@ async function testSignAndSubmit(transaction: string, orderId: string): Promise< } assert( - finalStatus === 'fulfilled' || finalStatus === 'completed', + finalStatus === 'completed', `Swap reached success state (got: ${finalStatus})` ); } @@ -364,8 +353,8 @@ async function main(): Promise { const executeResult = await testExecute(); if (executeResult) { - await testStatus(executeResult.orderId); - await testSignAndSubmit(executeResult.transaction, executeResult.orderId); + await testStatus(executeResult.requestId); + await testSignAndSubmit(executeResult.transaction, executeResult.requestId); } } catch (error) { console.error('\n 💥 Unexpected error:', error instanceof Error ? error.message : error); diff --git a/examples/node-cli/e2e/sdk-integration.ts b/examples/node-cli/e2e/sdk-integration.ts index 84f6c7c..6f2997b 100644 --- a/examples/node-cli/e2e/sdk-integration.ts +++ b/examples/node-cli/e2e/sdk-integration.ts @@ -125,35 +125,31 @@ async function testQuoteForPair( section(`Section 2 — Quote: ${pairLabel} (free, no payment)`); const quote: QuoteResponse = await client.getQuote({ - sourceChainId: 'solana', - sourceTokenAddress, - destinationChainId: 'base', - destinationTokenAddress, + sourceChain: 'solana', + sourceToken: sourceTokenAddress, + destinationChain: 'base', + destinationToken: destinationTokenAddress, amount: SWAP_AMOUNT, - senderAddress: TEST_SENDER, - recipientAddress: RECIPIENT_ADDRESS, + userWallet: TEST_SENDER, + recipient: RECIPIENT_ADDRESS, }); - assert(typeof quote.quoteId === 'string' && quote.quoteId.length > 0, 'Quote has quoteId'); - assert(typeof quote.sourceAmount === 'string', 'Quote has sourceAmount'); - assert(typeof quote.destinationAmount === 'string', 'Quote has destinationAmount'); + assert(typeof quote.estimatedOutput === 'string', 'Quote has estimatedOutput'); + assert(typeof quote.estimatedOutputFormatted === 'string', 'Quote has estimatedOutputFormatted'); + assert(typeof quote.estimatedTime === 'number', 'Quote has estimatedTime'); assert(typeof quote.fees === 'object', 'Quote has fees object'); - assert(typeof quote.fees.totalEstimatedFeeUsd === 'number', 'fees.totalEstimatedFeeUsd is a number'); - assert(typeof quote.fees.bridgeFeeUsd === 'number', 'fees.bridgeFeeUsd is a number'); - assert(typeof quote.fees.x402FeeUsd === 'number', 'fees.x402FeeUsd is a number'); - assert(typeof quote.fees.gasReimbursementEstimatedUsd === 'number', 'fees.gasReimbursementEstimatedUsd is a number'); - assert(typeof quote.estimatedTimeSeconds === 'number', 'Quote has estimatedTimeSeconds'); - assert(typeof quote.expiresIn === 'number', 'Quote has expiresIn'); - assert(typeof quote.expiresAt === 'string', 'Quote has expiresAt'); - - const destAmount = parseFloat(quote.destinationAmount); - assert(destAmount > Number(SWAP_AMOUNT) * 0.9, `Destination amount > 90% of input (got ${destAmount}, input ${SWAP_AMOUNT})`); - assert(quote.fees.totalEstimatedFeeUsd > 0, `Total fee > 0 (got ${quote.fees.totalEstimatedFeeUsd})`); - - console.log(`\n Quote ID: ${quote.quoteId}`); - console.log(` Destination amount: ${destAmount / 1e6}`); - console.log(` Total Fee: $${quote.fees.totalEstimatedFeeUsd}`); - console.log(` Expires in: ${quote.expiresIn}s`); + assert(typeof quote.fees.clawswap === 'string', 'fees.clawswap is a string'); + assert(typeof quote.fees.relay === 'string', 'fees.relay is a string'); + assert(typeof quote.fees.gas === 'string', 'fees.gas is a string'); + assert(typeof quote.route === 'object', 'Quote has route object'); + assert(typeof quote.supported === 'boolean', 'Quote has supported flag'); + + const destAmount = parseFloat(quote.estimatedOutput); + assert(destAmount > Number(SWAP_AMOUNT) * 0.9, `Estimated output > 90% of input (got ${destAmount}, input ${SWAP_AMOUNT})`); + + console.log(`\n Estimated output: ${quote.estimatedOutputFormatted}`); + console.log(` Fees — ClawSwap: ${quote.fees.clawswap} | Relay: ${quote.fees.relay} | Gas: ${quote.fees.gas}`); + console.log(` Estimated time: ${quote.estimatedTime}s`); return quote; } @@ -205,53 +201,49 @@ async function testExecute(): Promise { console.log(` Pair: ${execPairLabel}`); const response: ExecuteSwapResponse = await client.executeSwap({ - sourceChainId: 'solana', - sourceTokenAddress: EXEC_SOURCE_TOKEN, - destinationChainId: 'base', - destinationTokenAddress: EXEC_DEST_TOKEN, + sourceChain: 'solana', + sourceToken: EXEC_SOURCE_TOKEN, + destinationChain: 'base', + destinationToken: EXEC_DEST_TOKEN, amount: SWAP_AMOUNT, - senderAddress, - recipientAddress: RECIPIENT_ADDRESS, + userWallet: senderAddress, + recipient: RECIPIENT_ADDRESS, }); + assert(typeof response.requestId === 'string', 'executeSwap() returns requestId (string)'); assert(typeof response.transaction === 'string', 'executeSwap() returns transaction (string)'); - assert(response.transaction.length > 0, 'Transaction is non-empty'); - assert(typeof response.orderId === 'string', 'executeSwap() returns orderId (string)'); - assert(typeof response.isToken2022 === 'boolean', 'executeSwap() returns isToken2022 (boolean)'); - assert(typeof response.accounting === 'object', 'executeSwap() returns accounting object'); - assert(typeof response.accounting.x402Fee.amountUsd === 'number', 'accounting.x402Fee.amountUsd is a number'); - if (response.accounting.gasReimbursement) { - assert(typeof response.accounting.gasReimbursement.amountRaw === 'string', 'accounting.gasReimbursement.amountRaw is a string'); - assert(typeof response.accounting.gasReimbursement.amountFormatted === 'string', 'accounting.gasReimbursement.amountFormatted is a string'); - } - assert(typeof response.accounting.bridgeFee.estimatedUsd === 'number', 'accounting.bridgeFee.estimatedUsd is a number'); - - console.log(`\n Order ID: ${response.orderId}`); - console.log(` x402 Fee: $${response.accounting.x402Fee.amountUsd}`); - console.log(` Gas Reimbursement: ${response.accounting.gasReimbursement?.amountFormatted ?? 'N/A'}`); - -}dwa xmcfr + assert(response.transaction!.length > 0, 'Transaction is non-empty'); + assert(typeof response.sourceChain === 'string', 'executeSwap() returns sourceChain'); + assert(typeof response.estimatedOutput === 'string', 'executeSwap() returns estimatedOutput'); + assert(typeof response.estimatedTime === 'number', 'executeSwap() returns estimatedTime'); + assert(typeof response.fees === 'object', 'executeSwap() returns fees object'); + assert(typeof response.fees.clawswap === 'string', 'fees.clawswap is a string'); + assert(typeof response.instructions === 'string', 'executeSwap() returns instructions'); + + console.log(`\n Request ID: ${response.requestId}`); + console.log(` Estimated output: ${response.estimatedOutput}`); + console.log(` Fees — ClawSwap: ${response.fees.clawswap} | Relay: ${response.fees.relay} | Gas: ${response.fees.gas}`); + + return response; +} // ─── Section 4: Status ─────────────────────────────────────────────────────── -async function testStatus(client: ClawSwapClient, orderId: string): Promise { +async function testStatus(client: ClawSwapClient, requestId: string): Promise { section('Section 4 — Status via SDK (free)'); - const status: StatusResponse = await client.getStatus(orderId); + const status: StatusResponse = await client.getStatus(requestId); - const statusRecord = status as unknown as Record; - const id = statusRecord.swapId ?? statusRecord.orderId; - assert(typeof id === 'string', 'getStatus() returns swapId or orderId'); + assert(typeof status.requestId === 'string', 'Status has requestId'); assert(typeof status.status === 'string', 'Status has status field'); - assert(typeof status.sourceChainId === 'string', 'Status has sourceChainId'); - assert(typeof status.destinationChainId === 'string', 'Status has destinationChainId'); - assert(typeof status.sourceAmount === 'string', 'Status has sourceAmount'); - assert(typeof status.destinationAmount === 'string', 'Status has destinationAmount'); + assert(typeof status.sourceChain === 'string', 'Status has sourceChain'); + assert(typeof status.destinationChain === 'string', 'Status has destinationChain'); + assert(typeof status.outputAmount === 'string', 'Status has outputAmount'); - const validStatuses = ['pending', 'created', 'bridging', 'settling', 'fulfilled', 'completed', 'failed', 'cancelled']; + const validStatuses = ['pending', 'submitted', 'filling', 'completed', 'failed']; assert(validStatuses.includes(status.status), `Status "${status.status}" is a known value`); - console.log(`\n Order: ${id}`); + console.log(`\n Request: ${status.requestId}`); console.log(` Status: ${status.status}`); } @@ -260,7 +252,7 @@ async function testStatus(client: ClawSwapClient, orderId: string): Promise { section('Section 5 — Sign, Submit & waitForSettlement'); @@ -302,8 +294,8 @@ async function testSettlement( assert(!confirmation.value.err, 'Transaction confirmed on Solana'); // Use SDK to wait for settlement - console.log(`\n Calling client.waitForSettlement(${orderId})...`); - const result = await client.waitForSettlement(orderId, { + console.log(`\n Calling client.waitForSettlement(${requestId})...`); + const result = await client.waitForSettlement(requestId, { timeout: 300_000, interval: 3000, onStatusUpdate: (s) => { @@ -311,11 +303,11 @@ async function testSettlement( }, }); - const success = result.status === 'fulfilled' || result.status === 'completed'; + const success = result.status === 'completed'; assert(success, `Swap reached success state (got: ${result.status})`); if (success) { - console.log(`\n ✨ Swap completed: ${result.destinationAmount} tokens delivered`); + console.log(`\n ✨ Swap completed: ${result.outputAmount} tokens delivered`); } } @@ -351,8 +343,8 @@ async function main(): Promise { const executeResult = await testExecute(); if (executeResult) { - await testStatus(freeClient, executeResult.orderId); - await testSettlement(freeClient, executeResult.transaction, executeResult.orderId); + await testStatus(freeClient, executeResult.requestId); + await testSettlement(freeClient, executeResult.transaction!, executeResult.requestId); } } catch (error) { console.error('\n 💥 Unexpected error:', error instanceof Error ? error.message : error); From d9863b18092fbca895abc88903ddc697bf81ac76 Mon Sep 17 00:00:00 2001 From: WarTech9 Date: Thu, 26 Feb 2026 09:37:12 -0500 Subject: [PATCH 6/6] Fix lockfile not found issue --- .github/workflows/e2e-examples.yml | 2 +- package.json | 2 +- pnpm-lock.yaml | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e-examples.yml b/.github/workflows/e2e-examples.yml index 53644db..4b78eee 100644 --- a/.github/workflows/e2e-examples.yml +++ b/.github/workflows/e2e-examples.yml @@ -17,7 +17,7 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v2 with: - version: 8 + version: 10 - name: Setup Node.js uses: actions/setup-node@v4 diff --git a/package.json b/package.json index f24acfa..143d08d 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,6 @@ }, "engines": { "node": ">=18.0.0", - "pnpm": ">=8.0.0" + "pnpm": ">=9.0.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 637d0a8..7d58716 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9098,3 +9098,4 @@ snapshots: '@types/react': 18.3.28 react: 18.3.1 use-sync-external-store: 1.4.0(react@18.3.1) + \ No newline at end of file